@jasonshimmy/custom-elements-runtime 3.1.0 → 3.1.1
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/dist/custom-elements-runtime.cjs.js +1 -1
- package/dist/custom-elements-runtime.es.js +3 -3
- package/dist/custom-elements-runtime.jit-css.cjs.js +1 -1
- package/dist/custom-elements-runtime.jit-css.es.js +2 -2
- package/dist/custom-elements-runtime.router.cjs.js +1 -1
- package/dist/custom-elements-runtime.router.es.js +2 -2
- package/dist/custom-elements-runtime.ssr-middleware.cjs.js +1 -1
- package/dist/custom-elements-runtime.ssr-middleware.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.ssr-middleware.es.js +36 -30
- package/dist/custom-elements-runtime.ssr-middleware.es.js.map +1 -1
- package/dist/custom-elements-runtime.ssr.cjs.js +3 -3
- package/dist/custom-elements-runtime.ssr.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.ssr.es.js +121 -100
- package/dist/custom-elements-runtime.ssr.es.js.map +1 -1
- package/dist/{hooks-B50HhrHh.cjs → hooks-x8M4knLc.cjs} +4 -4
- package/dist/hooks-x8M4knLc.cjs.map +1 -0
- package/dist/{hooks-Cze3o-F7.js → hooks-xWZhQHco.js} +202 -199
- package/dist/hooks-xWZhQHco.js.map +1 -0
- package/dist/runtime/render.d.ts +0 -11
- package/dist/runtime/scheduler.d.ts +12 -0
- package/dist/runtime/ssr-context.d.ts +3 -1
- package/dist/runtime/ssr-utils.d.ts +9 -0
- package/dist/runtime/vdom-ssr-dsd.d.ts +25 -1
- package/dist/runtime/vdom-ssr.d.ts +2 -6
- package/dist/template-compiler-CTUhEHr8.cjs +22 -0
- package/dist/template-compiler-CTUhEHr8.cjs.map +1 -0
- package/dist/{template-compiler-DtpNsqE-.js → template-compiler-ZhSg1yPh.js} +902 -922
- package/dist/template-compiler-ZhSg1yPh.js.map +1 -0
- package/package.json +1 -1
- package/dist/hooks-B50HhrHh.cjs.map +0 -1
- package/dist/hooks-Cze3o-F7.js.map +0 -1
- package/dist/template-compiler-Cshhqxyd.cjs +0 -23
- package/dist/template-compiler-Cshhqxyd.cjs.map +0 -1
- package/dist/template-compiler-DtpNsqE-.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("./hooks-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("./hooks-x8M4knLc.cjs"),c=require("./template-compiler-CTUhEHr8.cjs"),k=require("./css-utils-RqkyBWft.cjs"),h=require("./logger-CSALKaYm.cjs");function O(e=document){if(typeof CustomEvent>"u")return;(e instanceof Document?e.documentElement:e).dispatchEvent(new CustomEvent("cer:hydrate",{bubbles:!0,composed:!0}))}const x=100,A=3e4;function D(e,t,r){return r==="jitCacheHitRate"?e<t*.5?"critical":e<t?"warning":"healthy":e>t*2?"critical":e>t?"warning":"healthy"}function U(e){const t=[];return e.memoryUsage?.status!=="healthy"&&t.push("Consider reducing component complexity or implementing better memory cleanup"),e.averageRenderTime?.status!=="healthy"&&t.push("Optimize component render functions - consider lazy loading or virtualization"),e.jitCacheHitRate?.status!=="healthy"&&t.push("JIT CSS cache performance is poor - review CSS patterns for optimization"),e.componentErrorRate?.status!=="healthy"&&t.push("High component error rate detected - review error handling and component logic"),e.activeReactiveStates?.status!=="healthy"&&t.push("High number of reactive states - consider state consolidation or cleanup"),e.memoryLeakIndicator?.status!=="healthy"&&t.push("Potential memory leak detected - review component cleanup and event listener management"),t}function v(){const e=new Map,t=new Set;let r=null;function o(s,i,a){e.set(s,{name:s,value:i,threshold:a,status:"healthy",lastUpdated:Date.now(),history:[]})}function l(){o("activeComponents",0,1e3),o("componentCreateRate",0,50),o("componentErrorRate",0,.1),o("memoryUsage",0,50*1024*1024),o("memoryGrowthRate",0,1024*1024),o("averageRenderTime",0,16),o("slowRenderCount",0,10),o("jitCacheHitRate",100,80),o("activeReactiveStates",0,5e3),o("dependencyUpdates",0,100),o("memoryLeakIndicator",0,.1)}function m(s,i){const a=e.get(s);a&&(a.value=i,a.lastUpdated=Date.now(),a.history.push(i),a.history.length>x&&a.history.shift(),a.status=D(i,a.threshold,s))}function u(){const s={};let i="healthy";for(const[a,d]of e)s[a]={...d},d.status==="critical"?i="critical":d.status==="warning"&&i==="healthy"&&(i="warning");return{overall:i,metrics:s,timestamp:Date.now(),recommendations:U(s)}}function f(){if("memory"in performance&&performance.memory){const s=performance.memory;m("memoryUsage",s.usedJSHeapSize);const i=e.get("memoryUsage");if(i&&i.history.length>1){const a=i.history[i.history.length-2],d=i.history[i.history.length-1];m("memoryGrowthRate",Math.max(0,d-a))}}}function w(s){for(const i of t)try{i(s)}catch(a){h.devError("Error in health monitor listener:",a)}}function _(){f();const s=u();w(s),s.overall==="critical"?h.devError("🚨 Runtime Health: Critical issues detected",s.recommendations):s.overall==="warning"&&h.devWarn("⚠️ Runtime Health: Performance warnings",s.recommendations)}function M(){typeof window>"u"||(r=setInterval(_,A))}function R(){r!==null&&(clearInterval(r),r=null)}function H(s){t.add(s)}function b(s){t.delete(s)}function L(s){const i=e.get(s);return i?[...i.history]:[]}function T(){for(const s of e.values())s.history=[]}return l(),M(),{updateMetric:m,getHealthReport:u,addListener:H,removeListener:b,stop:R,getMetricHistory:L,clearHistory:T}}let p=null;function g(){return p||(p=v()),p}function I(e,t){g().updateMetric(e,t)}function K(){return g().getHealthReport()}function C(){typeof window>"u"||typeof customElements>"u"||customElements.get("cer-keep-alive")||customElements.define("cer-keep-alive",P())}function P(){return class extends HTMLElement{_cache=new Map;_slot=null;_slotListener=null;connectedCallback(){this.shadowRoot||this.attachShadow({mode:"open"}),this.shadowRoot.querySelector("slot")||(this.shadowRoot.innerHTML="<slot></slot>"),this._slot=this.shadowRoot.querySelector("slot"),this._slot&&(this._slotListener=()=>this._handleSlotChange(),this._slot.addEventListener("slotchange",this._slotListener),this._handleSlotChange())}disconnectedCallback(){this._slot&&this._slotListener&&this._slot.removeEventListener("slotchange",this._slotListener),this._slotListener=null}clearCache(t){t?this._cache.delete(t):this._cache.clear()}_handleSlotChange(){if(!this._slot)return;const t=this._slot.assignedElements({flatten:!0});for(const r of t){const o=this._buildCacheKey(r);if(!this._cache.has(o))this._cache.set(o,r);else{const l=this._cache.get(o);if(l!==r)try{r.parentNode?.replaceChild(l,r)}catch{this._cache.set(o,r)}}}}_buildCacheKey(t){const r=t.tagName.toLowerCase(),o=t.getAttribute("id");return o?`${r}:${o}`:r}}}function E(){typeof customElements<"u"&&customElements.get("cer-suspense")||c.component("cer-suspense",()=>{const{pending:e}=n.useProps({pending:!1});return e?c.html`<slot name="fallback"><span>Loading…</span></slot>`:c.html`<slot></slot>`})}function S(){typeof customElements<"u"&&customElements.get("cer-error-boundary")||c.component("cer-error-boundary",()=>{const e=n.ref(!1),t=n.ref("");return n.useOnError(r=>{e.value=!0,t.value=r.message}),n.useExpose({_cerHandleChildError:r=>{e.peek()||(e.value=!0,t.value=r instanceof Error?r.message:String(r))},reset:()=>{e.value=!1,t.value=""}}),e.value?c.html`<slot name="fallback"
|
|
2
2
|
><div role="alert">
|
|
3
3
|
<strong>Something went wrong.</strong>
|
|
4
4
|
${t.value?c.html`<p>${t.value}</p>`:c.html``}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { r as f, u as L, a as T, b as k, c as x, g as A, i as D } from "./hooks-
|
|
2
|
-
import { R as te, d as ne, e as oe, f as re, h as se, j as ae, k as ie, l as ce, n as le, p as ue, s as de, m as he, o as me, q as fe, t as pe, v as ye, w as ge, x as ve, y as Ce, z as we, A as Ee, B as Se } from "./hooks-
|
|
3
|
-
import { c as v, h as l, v as p } from "./template-compiler-
|
|
1
|
+
import { r as f, u as L, a as T, b as k, c as x, g as A, i as D } from "./hooks-xWZhQHco.js";
|
|
2
|
+
import { R as te, d as ne, e as oe, f as re, h as se, j as ae, k as ie, l as ce, n as le, p as ue, s as de, m as he, o as me, q as fe, t as pe, v as ye, w as ge, x as ve, y as Ce, z as we, A as Ee, B as Se } from "./hooks-xWZhQHco.js";
|
|
3
|
+
import { c as v, h as l, v as p } from "./template-compiler-ZhSg1yPh.js";
|
|
4
4
|
import { c as Re } from "./css-utils-Cg4o1MqY.js";
|
|
5
5
|
import { d as y, a as I } from "./logger-BvkEbVM4.js";
|
|
6
6
|
import { b as Me, s as be } from "./logger-BvkEbVM4.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./hooks-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./hooks-x8M4knLc.cjs"),e=require("./style-D40DsIqJ.cjs");function o(s){if(t.isDiscoveryRender$1())return;const r=t.getCurrentComponentContext()?._host?.shadowRoot??null;r?e.registerJITCSSComponent(r,s):e.enableJITCSS(s)}function a(s){return s}exports.useDesignTokens=t.useDesignTokens;exports.useGlobalStyle=t.useGlobalStyle;exports.colors=e.colors;exports.containerVariants=e.containerVariants;exports.disableJITCSS=e.disableJITCSS;exports.enableJITCSS=e.enableJITCSS;exports.extractClassesFromHTML=e.extractClassesFromHTML;exports.getJITCSSOptions=e.getJITCSSOptions;exports.isJITCSSEnabled=e.isJITCSSEnabled;exports.isJITCSSEnabledFor=e.isJITCSSEnabledFor;exports.jitCSS=e.jitCSS;exports.mediaVariants=e.mediaVariants;exports.parseArbitrary=e.parseArbitrary;exports.parseColorClass=e.parseColorClass;exports.parseColorWithOpacity=e.parseColorWithOpacity;exports.parseGradientColorStop=e.parseGradientColorStop;exports.parseSpacing=e.parseSpacing;exports.registerJITCSSComponent=e.registerJITCSSComponent;exports.selectorVariants=e.selectorVariants;exports.utilityMap=e.utilityMap;exports.cls=a;exports.useJITCSS=o;
|
|
2
2
|
//# sourceMappingURL=custom-elements-runtime.jit-css.cjs.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { g as o,
|
|
2
|
-
import { o as m, t as u } from "./hooks-
|
|
1
|
+
import { g as o, Q as e } from "./hooks-xWZhQHco.js";
|
|
2
|
+
import { o as m, t as u } from "./hooks-xWZhQHco.js";
|
|
3
3
|
import { r, e as t } from "./style-BmyOIMcU.js";
|
|
4
4
|
import { c as f, a as T, d as b, b as g, g as h, i as I, f as J, j as x, m as y, p as R, h as V, k as j, l as k, n as w, s as D, u as E } from "./style-BmyOIMcU.js";
|
|
5
5
|
function S(s) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./logger-CSALKaYm.cjs"),R=require("./hooks-B50HhrHh.cjs"),D=require("./template-compiler-Cshhqxyd.cjs"),ct=require("./custom-elements-runtime.store.cjs.js"),St=require("./custom-elements-runtime.directives.cjs.js"),at={enabled:!0,offset:0,timeoutMs:2e3},et=t=>t?typeof URLSearchParams>"u"?{}:Object.fromEntries(new URLSearchParams(t)):{},ht=t=>{if(!t||Object.keys(t).length===0)return"";try{return"?"+new URLSearchParams(t).toString()}catch{return""}},ot=t=>t?/^\s*javascript\s*:/i.test(t):!1,B=t=>/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(t)||t.startsWith("//"),pt=t=>{try{return decodeURIComponent(t)}catch{return t}};function A(t){if(!t)return"/";let r=t.replace(/\/+/g,"/");return r.startsWith("/")||(r="/"+r),r.length>1&&r.endsWith("/")&&(r=r.slice(0,-1)),r}const yt=t=>{if(!t)return"";const r=A(t);return r==="/"?"":r},it=new WeakMap;function Rt(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Et(t){const r=t.path||"/",y=A(r),a=y==="/"?[]:y.split("/").filter(Boolean),i=[],o=[];for(let l=0;l<a.length;l++){const u=a[l];if(u==="*"){if(l!==a.length-1)return c.devWarn(`Route '${t.path}' contains a '*' splat in a non-terminal position; splats must be the last segment. This route will be ignored.`),{invalid:!0};const P=`splat${i.length}`;i.push(P),o.push("__SPLAT__");continue}const m=u.match(/^:([A-Za-z0-9_-]+)(\*)?$/);if(m){const P=m[1],W=!!m[2];if(W&&l!==a.length-1)return c.devWarn(`Route '${t.path}' contains a splat param ':${P}*' in a non-terminal position; splats must be the last segment. This route will be ignored.`),{invalid:!0};i.push(P),o.push(W?"__SPLAT__":"([^/]+)");continue}o.push(Rt(u))}let w;if(o.length===0)w="^/$";else if(o[o.length-1]==="__SPLAT__"){const u=o.slice(0,-1).join("/");u?w=`^/${u}(?:/(.*))?(?:/)?$`:w="^(?:/(.*))?(?:/)?$"}else w=`^/${o.join("/")}(?:/)?$`;try{return{regex:new RegExp(w),paramNames:i}}catch(l){return c.devWarn(`Failed to compile route regex for '${t.path}': ${String(l)}`),{invalid:!0}}}const K=(t,r)=>{const y=A(r);for(const a of t){let i=it.get(a);if(i||(i=Et(a),it.set(a,i)),i.invalid)continue;const{regex:o,paramNames:w}=i,l=o.exec(y);if(l){const u={};for(let m=0;m<w.length;m++){const P=l[m+1]||"";u[w[m]]=P?pt(P):""}return{route:a,params:u}}}return{route:null,params:{}}};function Z(t,r){for(const y of t)if(K([y],r).route!==null)return y;return null}function $t(t,r){const y=r.split("?")[0].split("#")[0];return K(t,y)}const lt=50;let G={},j={};function mt(){G={},j={}}function Ct(){const t=Object.entries(G);if(t.length<=lt)return;const y=t.sort(([,a],[,i])=>a.lastAccessed-i.lastAccessed).slice(0,t.length-lt);for(const[a]of y)delete G[a]}async function vt(t){if(t.component)return t.component;if(t.load){const r=G[t.path];if(r)return r.lastAccessed=Date.now(),r.component;if(j[t.path]!==void 0)return j[t.path];const y=typeof window>"u";try{const a=t.load().then(i=>{Ct();const o=i.default;return G[t.path]={component:o,lastAccessed:Date.now()},delete j[t.path],o}).catch(i=>{delete j[t.path];const o=i instanceof Error?i.message:String(i);throw y&&c.devError(`SSR component load failed for route: ${t.path}. ${o}`),new Error(`Failed to load component for route: ${t.path}. ${o}`)});return j[t.path]=a,await a}catch(a){const i=a instanceof Error?a.message:String(a);throw new Error(`Failed to load component for route: ${t.path}. ${i}`,{cause:a})}}throw new Error(`No component or loader defined for route: ${t.path}`)}let v=null;function At(t){v=t}function ut(){return v}const V=new Set;let I=null;function gt(){if(I){try{I()}catch{}I=null}if(v)try{let t=!1;I=v.subscribe(r=>{t=!0;for(const y of V)try{y(r)}catch{}});try{C.base=v.base}catch{}if(t){const r=v.getCurrent();for(const y of V)try{y(r)}catch{}}else{const r=v.getCurrent();for(const y of V)try{y(r)}catch{}}try{typeof window<"u"&&R.flushDOMUpdates()}catch{}}catch{I=null}}function Pt(){gt()}const C={store:{subscribe(t){if(v)return v.store.subscribe(t);try{t({path:"/",params:{},query:{}})}catch{}return()=>{}},getState(){return v?v.getCurrent():{path:"/",params:{},query:{}}},setState(t){if(v)try{v.store.setState(t)}catch{}}},subscribe(t){if(typeof t!="function")return c.devWarn("activeRouterProxy.subscribe: listener must be a function"),()=>{};if(V.add(t),v)if(!I)gt();else try{const r=v.getCurrent();r&&t(r)}catch(r){c.devWarn("activeRouterProxy subscription failed",r)}else try{t({path:"/",params:{},query:{}})}catch(r){c.devWarn("activeRouterProxy fallback state delivery failed",r)}return()=>{try{if(V.delete(t),V.size===0&&I){try{I()}catch(r){c.devWarn("activeRouterProxy inner unsubscribe failed",r)}I=null}}catch(r){c.devWarn("activeRouterProxy unsubscribe failed",r)}}},getCurrent(){return v?v.getCurrent():{path:"/",params:{},query:{}}},async push(t){return v?v.push(t):Promise.resolve()},async replace(t){return v?v.replace(t):Promise.resolve()},back(){if(v)return v.back()},matchRoute(t){return v?v.matchRoute(t):{route:null,params:{}}},resolveRouteComponent(t){return v?v.resolveRouteComponent(t):Promise.reject(new Error("No active router"))},base:"",scrollToFragment(t){return v?v.scrollToFragment(t):Promise.resolve(!1)},destroy(){v&&v.destroy()}};function bt(t){const{routes:r,base:y="",initialUrl:a,scrollToFragment:i=!0}=t,o=yt(y),w=typeof i=="boolean"?{...at,enabled:i}:{...at,...i};let l,u,m,P,W,L,H,J=()=>{};const _=new Set,F=10;let k=0;const X=async(s,f)=>{const e=Z(r,s.path);if(!e||!e.beforeEnter)return!0;try{const n=await e.beforeEnter(s,f);if(typeof n=="string"){const h=`${s.path}->${n}`;return _.has(h)||k>=F?(c.devError(`Redirect loop detected: ${h}`),!1):n}return n!==!1}catch(n){c.devError("beforeEnter error",n);try{m.setState(f)}catch{}throw n}},rt=async(s,f)=>{const e=Z(r,s.path);if(!e||!e.onEnter)return!0;try{const n=await e.onEnter(s,f);if(typeof n=="string"){const h=`${s.path}->${n}`;return _.has(h)||k>=F?(c.devError(`Redirect loop detected: ${h}`),!1):n}return n!==!1}catch(n){c.devError("onEnter error",n);try{m.setState(f)}catch{}throw n}},Y=(s,f)=>{const e=Z(r,s.path);if(!(!e||!e.afterEnter))try{const n=e.afterEnter(s,f);n instanceof Promise&&n.catch(h=>{c.devError("afterEnter async error",h)})}catch(n){c.devError("afterEnter error",n)}},x=new Map,U=100,O=s=>{if(x.has(s))return x.get(s);const f=K(r,s);if(x.size>=U){const e=Math.floor(U*.25),n=Array.from(x.keys());for(let h=0;h<e&&h<n.length;h++)x.delete(n[h])}return x.set(s,f),f},tt=()=>{};async function p(s,f=0){try{const e=document.getElementById(s);if(!e)return!1;if(f>0)try{const n=e.getBoundingClientRect(),h=Math.max(0,window.scrollY+n.top-f);typeof window.scrollTo=="function"&&window.scrollTo({top:h,behavior:"auto"})}catch{try{e.scrollIntoView()}catch{return!1}}else if(typeof e.scrollIntoView=="function")try{e.scrollIntoView({behavior:"auto",block:"start",inline:"nearest"})}catch{try{e.scrollIntoView()}catch{return!1}}return!0}catch{return!1}}function E(s,f=0,e=2e3){return new Promise(n=>{let h=!1,g=null,b=null;const $=Date.now(),S=T=>{h||(h=!0,g&&clearTimeout(g),b!==null&&cancelAnimationFrame(b),n(T))},z=async()=>{if(!h)try{if(await p(s,f))return S(!0);const T=async()=>{if(h)return;if(Date.now()-$>=e)return S(!1);try{if(await p(s,f))return S(!0);b=requestAnimationFrame(T)}catch(wt){c.devWarn("Scroll retry attempt failed:",wt),b=requestAnimationFrame(T)}};b=requestAnimationFrame(T)}catch(T){c.devWarn("Initial scroll attempt failed:",T),S(!1)}};g=setTimeout(()=>{S(!1)},e),z().catch(T=>{c.devWarn("Scroll attempt failed:",T),S(!1)})})}let d=!1;const q=async(s,f=!1)=>{if(d){c.devWarn(`Navigation to ${s} blocked - navigation already in progress`);return}d=!0,k=0,_.clear();try{await N(s,f)}finally{d=!1,k=0,_.clear()}},M=s=>{const f=s.indexOf("#"),e=f>=0?s.slice(f+1):"",n=f>=0?s.slice(0,f):s,h=n.indexOf("?"),g=h>=0?n.slice(0,h):n,b=h>=0?et(n.slice(h)):{},$=g.startsWith(o)?g.slice(o.length):g;return{path:A($||"/"),query:b,fragment:e}},N=async(s,f=!1)=>{try{const e=M(s),n=O(e.path);if(!n.route)throw new Error(`No route found for ${e.path}`);const h=m.getState(),g={path:e.path,params:n.params,query:e.query,fragment:e.fragment},b=await X(g,h);if(b===!1)return;if(typeof b=="string"){k++;const S=`${g.path}->${b}`;_.add(S),await N(b,!0);return}const $=await rt(g,h);if($===!1)return;if(typeof $=="string"){k++;const S=`${g.path}->${$}`;_.add(S),await N($,!0);return}if(typeof window<"u"&&typeof document<"u"){const S=ht(e.query),z=o+e.path+(S||"")+(e.fragment?"#"+e.fragment:"");f?window.history.replaceState({},"",z):window.history.pushState({},"",z)}if(m.setState(g),Y(g,h),typeof window<"u"&&typeof document<"u")try{const S=g.fragment;w.enabled&&S&&E(String(S),w.offset,w.timeoutMs).catch(()=>{})}catch{}}catch(e){if(c.devError("Navigation error:",e),e instanceof Error&&(e.stack?.includes("runBeforeEnter")||e.stack?.includes("runOnEnter")))throw e;try{const n=m.getState();if(!K(r,n.path).route){let g=r.find(b=>b.path==="/");if(g||(g=r.find(b=>!b.path.includes(":")&&!b.path.includes("*"))),!g&&r.length>0&&(g=r[0]),g){const b=K(r,g.path);m.setState({path:g.path,params:b.params,query:{}})}else c.devError("No fallback route available for error recovery")}}catch(n){c.devWarn("State recovery failed during navigation error:",n)}}};if((s=>{if(!s||s.length===0)return c.devError("Router configuration error: No routes provided"),!1;const f=new Set;for(const e of s){if(!e.path)return c.devError("Router configuration error: Route missing path",e),!1;f.has(e.path)&&c.devWarn(`Duplicate route path detected: ${e.path}`),f.add(e.path),!e.component&&!e.load&&c.devWarn(`Route '${e.path}' has no component or load function`)}return!0})(r),typeof window>"u"||typeof a<"u"){for(const s of r)O(s.path);c.devWarn(`Pre-compiled ${r.length} routes for SSR`)}if(typeof window<"u"&&typeof document<"u"&&typeof a>"u"){l=()=>{try{const e=new URL(window.location.href),n=e.pathname,h=n.startsWith(o)?n.slice(o.length):n,g=A(h||"/"),b=et(e.search),$=e.hash&&e.hash.length?e.hash.slice(1):"";return{path:g,query:b,fragment:$}}catch(e){return c.devWarn("Invalid URL detected, falling back to safe defaults",e),{path:"/",query:{},fragment:""}}},u=l();const s=O(u.path);m=ct.createStore({path:u.path,params:s.params,query:u.query,fragment:u.fragment}),P=async(e=!1)=>{const n=l();await q(n.path,e)};const f=()=>P(!0);window.addEventListener("popstate",f),J=()=>window.removeEventListener("popstate",f),W=e=>q(e,!1),L=e=>q(e,!0),H=()=>window.history.back()}else{l=()=>{try{const e=new URL(a||"/","http://localhost"),n=e.pathname,h=n.startsWith(o)?n.slice(o.length):n,g=A(h||"/"),b=et(e.search),$=e.hash&&e.hash.length?e.hash.slice(1):"";return{path:g,query:b,fragment:$}}catch(e){return c.devWarn("Invalid SSR URL detected, falling back to safe defaults",e),{path:"/",query:{},fragment:""}}},u=l();const s=O(u.path);m=ct.createStore({path:u.path,params:s.params,query:u.query,fragment:u.fragment}),P=async()=>{const e=l();await f(e.path)};const f=async e=>{if(k++,k>F){c.devError(`SSR redirect depth exceeded for path: ${e}`);return}try{const n=M(e),h=O(n.path);if(!h.route)throw new Error(`No route found for ${n.path}`);const g=m.getState(),b={path:n.path,params:h.params,query:n.query,fragment:n.fragment},$=Z(r,b.path);if($?.beforeEnter){const S=await $.beforeEnter(b,g);if(typeof S=="string"){const z=`${b.path}->${S}`;_.add(z),await f(S);return}if(S===!1)return}if($?.onEnter){const S=await $.onEnter(b,g);if(typeof S=="string"){const z=`${b.path}->${S}`;_.add(z),await f(S);return}if(S===!1)return}m.setState(b),$?.afterEnter&&$.afterEnter(b,g)}catch(n){throw c.devError("SSR navigation error:",n),n}};W=async e=>(k=0,_.clear(),f(e)),L=async e=>(k=0,_.clear(),f(e)),H=()=>{}}return{_cleanupScrollState:tt,destroy:J,store:m,push:W,replace:L,back:H,subscribe:m.subscribe,matchRoute:s=>O(s),getCurrent:()=>m.getState(),resolveRouteComponent:vt,base:o,scrollToFragment:s=>{const f=s||m.getState().fragment;return!f||typeof window>"u"||typeof document>"u"?Promise.resolve(!1):E(f,w.offset,w.timeoutMs)}}}function Wt(t){mt();const r=bt(t),y=ut();if(y){try{y.destroy()}catch{}try{y._cleanupScrollState?.()}catch{}}At(r);try{Pt();try{typeof window<"u"&&R.flushDOMUpdates()}catch{}try{typeof window<"u"&&queueMicrotask(()=>{try{R.flushDOMUpdates()}catch{}})}catch{}}catch{}return D.component("router-view",async()=>{if(!ut())return D.html`<div>Router not initialized.</div>`;const a=R.ref(C.getCurrent()),i=typeof window>"u";let o;i||(R.useOnConnected(()=>{try{typeof C.subscribe=="function"&&(o=C.subscribe(l=>{try{l&&typeof l=="object"&&typeof l.path=="string"?a.value=l:(c.devWarn("router-view received invalid state",l),a.value={path:"/",params:{},query:{}})}catch(u){c.devWarn("router-view subscription update failed",u);try{a.value={path:"/",params:{},query:{}}}catch{}}}))}catch(l){c.devWarn("router-view subscribe failed",l)}}),R.useOnDisconnected(()=>{if(typeof o=="function"){try{o()}catch(l){c.devWarn("router-view unsubscribe failed",l)}o=void 0}}));const w=C.matchRoute(a.value.path);if(!w||!w.route)return D.html`<div>Not found</div>`;try{const u=await C.resolveRouteComponent(w.route);if(typeof u=="string")return{tag:u,props:{},children:[]};if(typeof u=="function"){const m=u();return(m instanceof Promise?m:Promise.resolve(m)).then(W=>typeof W=="string"?{tag:W,props:{},children:[]}:W)}return D.html`<div>Invalid route component</div>`}catch{return D.html`<div>Invalid route component</div>`}}),D.component("router-link",()=>{const a=R.useProps({to:"",tag:"a",replace:!1,exact:!1,activeClass:"active",exactActiveClass:"exact-active",ariaCurrentValue:"page",disabled:!1,external:!1,class:"",style:""}),i=typeof window>"u",o=R.ref(C.getCurrent()),w=o.value?.path||"/",l=String(a.to||""),u=i?{isExactActive:ft(w,l,C.base),isActive:dt(w,l,C.base),isExternal:B(l)||!!a.external}:null;let m;R.useStyle(()=>"a,button{display:inline-block;}");const P=R.ref(a.class||""),W=R.ref(a.style||"");if(!i){let p=null;R.useOnConnected(E=>{try{if(typeof C.subscribe=="function"){m=C.subscribe(d=>{try{d&&typeof d=="object"&&typeof d.path=="string"?o.value=d:(c.devWarn("router-link received invalid state",d),o.value={path:"/",params:{},query:{}})}catch(q){c.devWarn("router-link subscription update failed",q);try{o.value={path:"/",params:{},query:{}}}catch{}}});try{const d=C.getCurrent();d&&typeof d.path=="string"&&(o.value=d)}catch(d){c.devWarn("router-link initial state sync failed",d)}p=setInterval(()=>{try{const d=C.getCurrent();d&&typeof d.path=="string"&&JSON.stringify(o.value)!==JSON.stringify(d)&&(o.value=d)}catch{}},100)}}catch(d){c.devWarn("router-link subscribe failed",d)}try{const d=E?._host;if(d instanceof HTMLElement){const q=d.getAttribute("class"),M=d.getAttribute("style");q&&(P.value=q),M&&(W.value=M),q!==null&&d.removeAttribute("class"),M!==null&&d.removeAttribute("style");try{E?._requestRender?.();try{R.flushDOMUpdates()}catch{}}catch{}}}catch(d){c.devWarn("router-link host migration failed",d)}}),R.useOnDisconnected(()=>{if(typeof m=="function")try{m()}catch(E){c.devWarn("router-link unsubscribe failed",E)}finally{m=void 0}if(p)try{clearInterval(p)}catch(E){c.devWarn("router-link sync interval cleanup failed",E)}finally{p=null}})}const L=R.computed(()=>{if(i&&u)return u.isExactActive;try{const p=C.base??"",E=a.to||"";return!o.value||typeof o.value.path!="string"?!1:ft(o.value.path,E,p)}catch(p){return c.devWarn("isExactActive computation error",p),!1}}),H=R.computed(()=>{if(i&&u)return u.isActive;try{const p=C.base??"",E=a.to||"";return!o.value||typeof o.value.path!="string"?!1:a.exact?L.value:dt(o.value.path,E,p)}catch(p){return c.devWarn("isActive computation error",p),!1}}),J=R.computed(()=>{const p=String(a.to||"");if(ot(p))return null;if(B(p))return p;const[E,d]=p.split("#"),[q,M]=(E||"").split("?"),N=C.base??"";let Q=q||"/";if(N&&N!=="/"){const nt=A(N),s=A(Q);s.startsWith(nt)?Q=s.slice(nt.length)||"/":Q=s}const st=A(Q||"/");return N+st+(M?"?"+M:"")+(d?"#"+d:"")}),_=R.computed(()=>{const E=(P&&P.value||a.class||"").split(/\s+/).filter(Boolean),d={};for(const q of E)d[q]=!0;return d}),F=R.computed(()=>({..._.value,[a.activeClass||"active"]:H.value,[a.exactActiveClass||"exact-active"]:L.value})),k=R.computed(()=>Object.keys(F.value).filter(p=>F.value[p]).join(" ")),X=R.computed(()=>a.tag||"a"),rt=R.computed(()=>X.value==="button"),Y=R.computed(()=>L.value?a.ariaCurrentValue:null),x=R.computed(()=>!!a.disabled),U=R.computed(()=>{const p=String(a.to||"");return(B(p)||!!a.external)&&X.value==="a"}),O=R.computed(()=>W&&W.value||a.style||""),tt=p=>{if(p.defaultPrevented||p.button!==0||p.metaKey||p.altKey||p.ctrlKey||p.shiftKey)return;if(x.value){p.preventDefault();return}const E=String(a.to||"");if(ot(E)){try{p.preventDefault()}catch{}c.devWarn("Blocked unsafe javascript: URI in router-link.to");return}U.value||(p.preventDefault(),a.replace?C.replace(a.to):C.push(a.to))};return D.html`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./logger-CSALKaYm.cjs"),R=require("./hooks-x8M4knLc.cjs"),D=require("./template-compiler-CTUhEHr8.cjs"),ct=require("./custom-elements-runtime.store.cjs.js"),St=require("./custom-elements-runtime.directives.cjs.js"),at={enabled:!0,offset:0,timeoutMs:2e3},et=t=>t?typeof URLSearchParams>"u"?{}:Object.fromEntries(new URLSearchParams(t)):{},ht=t=>{if(!t||Object.keys(t).length===0)return"";try{return"?"+new URLSearchParams(t).toString()}catch{return""}},ot=t=>t?/^\s*javascript\s*:/i.test(t):!1,B=t=>/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(t)||t.startsWith("//"),pt=t=>{try{return decodeURIComponent(t)}catch{return t}};function A(t){if(!t)return"/";let r=t.replace(/\/+/g,"/");return r.startsWith("/")||(r="/"+r),r.length>1&&r.endsWith("/")&&(r=r.slice(0,-1)),r}const yt=t=>{if(!t)return"";const r=A(t);return r==="/"?"":r},it=new WeakMap;function Rt(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Et(t){const r=t.path||"/",y=A(r),a=y==="/"?[]:y.split("/").filter(Boolean),i=[],o=[];for(let l=0;l<a.length;l++){const u=a[l];if(u==="*"){if(l!==a.length-1)return c.devWarn(`Route '${t.path}' contains a '*' splat in a non-terminal position; splats must be the last segment. This route will be ignored.`),{invalid:!0};const P=`splat${i.length}`;i.push(P),o.push("__SPLAT__");continue}const m=u.match(/^:([A-Za-z0-9_-]+)(\*)?$/);if(m){const P=m[1],W=!!m[2];if(W&&l!==a.length-1)return c.devWarn(`Route '${t.path}' contains a splat param ':${P}*' in a non-terminal position; splats must be the last segment. This route will be ignored.`),{invalid:!0};i.push(P),o.push(W?"__SPLAT__":"([^/]+)");continue}o.push(Rt(u))}let w;if(o.length===0)w="^/$";else if(o[o.length-1]==="__SPLAT__"){const u=o.slice(0,-1).join("/");u?w=`^/${u}(?:/(.*))?(?:/)?$`:w="^(?:/(.*))?(?:/)?$"}else w=`^/${o.join("/")}(?:/)?$`;try{return{regex:new RegExp(w),paramNames:i}}catch(l){return c.devWarn(`Failed to compile route regex for '${t.path}': ${String(l)}`),{invalid:!0}}}const K=(t,r)=>{const y=A(r);for(const a of t){let i=it.get(a);if(i||(i=Et(a),it.set(a,i)),i.invalid)continue;const{regex:o,paramNames:w}=i,l=o.exec(y);if(l){const u={};for(let m=0;m<w.length;m++){const P=l[m+1]||"";u[w[m]]=P?pt(P):""}return{route:a,params:u}}}return{route:null,params:{}}};function Z(t,r){for(const y of t)if(K([y],r).route!==null)return y;return null}function $t(t,r){const y=r.split("?")[0].split("#")[0];return K(t,y)}const lt=50;let G={},j={};function mt(){G={},j={}}function Ct(){const t=Object.entries(G);if(t.length<=lt)return;const y=t.sort(([,a],[,i])=>a.lastAccessed-i.lastAccessed).slice(0,t.length-lt);for(const[a]of y)delete G[a]}async function vt(t){if(t.component)return t.component;if(t.load){const r=G[t.path];if(r)return r.lastAccessed=Date.now(),r.component;if(j[t.path]!==void 0)return j[t.path];const y=typeof window>"u";try{const a=t.load().then(i=>{Ct();const o=i.default;return G[t.path]={component:o,lastAccessed:Date.now()},delete j[t.path],o}).catch(i=>{delete j[t.path];const o=i instanceof Error?i.message:String(i);throw y&&c.devError(`SSR component load failed for route: ${t.path}. ${o}`),new Error(`Failed to load component for route: ${t.path}. ${o}`)});return j[t.path]=a,await a}catch(a){const i=a instanceof Error?a.message:String(a);throw new Error(`Failed to load component for route: ${t.path}. ${i}`,{cause:a})}}throw new Error(`No component or loader defined for route: ${t.path}`)}let v=null;function At(t){v=t}function ut(){return v}const V=new Set;let I=null;function gt(){if(I){try{I()}catch{}I=null}if(v)try{let t=!1;I=v.subscribe(r=>{t=!0;for(const y of V)try{y(r)}catch{}});try{C.base=v.base}catch{}if(t){const r=v.getCurrent();for(const y of V)try{y(r)}catch{}}else{const r=v.getCurrent();for(const y of V)try{y(r)}catch{}}try{typeof window<"u"&&R.flushDOMUpdates()}catch{}}catch{I=null}}function Pt(){gt()}const C={store:{subscribe(t){if(v)return v.store.subscribe(t);try{t({path:"/",params:{},query:{}})}catch{}return()=>{}},getState(){return v?v.getCurrent():{path:"/",params:{},query:{}}},setState(t){if(v)try{v.store.setState(t)}catch{}}},subscribe(t){if(typeof t!="function")return c.devWarn("activeRouterProxy.subscribe: listener must be a function"),()=>{};if(V.add(t),v)if(!I)gt();else try{const r=v.getCurrent();r&&t(r)}catch(r){c.devWarn("activeRouterProxy subscription failed",r)}else try{t({path:"/",params:{},query:{}})}catch(r){c.devWarn("activeRouterProxy fallback state delivery failed",r)}return()=>{try{if(V.delete(t),V.size===0&&I){try{I()}catch(r){c.devWarn("activeRouterProxy inner unsubscribe failed",r)}I=null}}catch(r){c.devWarn("activeRouterProxy unsubscribe failed",r)}}},getCurrent(){return v?v.getCurrent():{path:"/",params:{},query:{}}},async push(t){return v?v.push(t):Promise.resolve()},async replace(t){return v?v.replace(t):Promise.resolve()},back(){if(v)return v.back()},matchRoute(t){return v?v.matchRoute(t):{route:null,params:{}}},resolveRouteComponent(t){return v?v.resolveRouteComponent(t):Promise.reject(new Error("No active router"))},base:"",scrollToFragment(t){return v?v.scrollToFragment(t):Promise.resolve(!1)},destroy(){v&&v.destroy()}};function bt(t){const{routes:r,base:y="",initialUrl:a,scrollToFragment:i=!0}=t,o=yt(y),w=typeof i=="boolean"?{...at,enabled:i}:{...at,...i};let l,u,m,P,W,L,H,J=()=>{};const _=new Set,F=10;let k=0;const X=async(s,f)=>{const e=Z(r,s.path);if(!e||!e.beforeEnter)return!0;try{const n=await e.beforeEnter(s,f);if(typeof n=="string"){const h=`${s.path}->${n}`;return _.has(h)||k>=F?(c.devError(`Redirect loop detected: ${h}`),!1):n}return n!==!1}catch(n){c.devError("beforeEnter error",n);try{m.setState(f)}catch{}throw n}},rt=async(s,f)=>{const e=Z(r,s.path);if(!e||!e.onEnter)return!0;try{const n=await e.onEnter(s,f);if(typeof n=="string"){const h=`${s.path}->${n}`;return _.has(h)||k>=F?(c.devError(`Redirect loop detected: ${h}`),!1):n}return n!==!1}catch(n){c.devError("onEnter error",n);try{m.setState(f)}catch{}throw n}},Y=(s,f)=>{const e=Z(r,s.path);if(!(!e||!e.afterEnter))try{const n=e.afterEnter(s,f);n instanceof Promise&&n.catch(h=>{c.devError("afterEnter async error",h)})}catch(n){c.devError("afterEnter error",n)}},x=new Map,U=100,O=s=>{if(x.has(s))return x.get(s);const f=K(r,s);if(x.size>=U){const e=Math.floor(U*.25),n=Array.from(x.keys());for(let h=0;h<e&&h<n.length;h++)x.delete(n[h])}return x.set(s,f),f},tt=()=>{};async function p(s,f=0){try{const e=document.getElementById(s);if(!e)return!1;if(f>0)try{const n=e.getBoundingClientRect(),h=Math.max(0,window.scrollY+n.top-f);typeof window.scrollTo=="function"&&window.scrollTo({top:h,behavior:"auto"})}catch{try{e.scrollIntoView()}catch{return!1}}else if(typeof e.scrollIntoView=="function")try{e.scrollIntoView({behavior:"auto",block:"start",inline:"nearest"})}catch{try{e.scrollIntoView()}catch{return!1}}return!0}catch{return!1}}function E(s,f=0,e=2e3){return new Promise(n=>{let h=!1,g=null,b=null;const $=Date.now(),S=T=>{h||(h=!0,g&&clearTimeout(g),b!==null&&cancelAnimationFrame(b),n(T))},z=async()=>{if(!h)try{if(await p(s,f))return S(!0);const T=async()=>{if(h)return;if(Date.now()-$>=e)return S(!1);try{if(await p(s,f))return S(!0);b=requestAnimationFrame(T)}catch(wt){c.devWarn("Scroll retry attempt failed:",wt),b=requestAnimationFrame(T)}};b=requestAnimationFrame(T)}catch(T){c.devWarn("Initial scroll attempt failed:",T),S(!1)}};g=setTimeout(()=>{S(!1)},e),z().catch(T=>{c.devWarn("Scroll attempt failed:",T),S(!1)})})}let d=!1;const q=async(s,f=!1)=>{if(d){c.devWarn(`Navigation to ${s} blocked - navigation already in progress`);return}d=!0,k=0,_.clear();try{await N(s,f)}finally{d=!1,k=0,_.clear()}},M=s=>{const f=s.indexOf("#"),e=f>=0?s.slice(f+1):"",n=f>=0?s.slice(0,f):s,h=n.indexOf("?"),g=h>=0?n.slice(0,h):n,b=h>=0?et(n.slice(h)):{},$=g.startsWith(o)?g.slice(o.length):g;return{path:A($||"/"),query:b,fragment:e}},N=async(s,f=!1)=>{try{const e=M(s),n=O(e.path);if(!n.route)throw new Error(`No route found for ${e.path}`);const h=m.getState(),g={path:e.path,params:n.params,query:e.query,fragment:e.fragment},b=await X(g,h);if(b===!1)return;if(typeof b=="string"){k++;const S=`${g.path}->${b}`;_.add(S),await N(b,!0);return}const $=await rt(g,h);if($===!1)return;if(typeof $=="string"){k++;const S=`${g.path}->${$}`;_.add(S),await N($,!0);return}if(typeof window<"u"&&typeof document<"u"){const S=ht(e.query),z=o+e.path+(S||"")+(e.fragment?"#"+e.fragment:"");f?window.history.replaceState({},"",z):window.history.pushState({},"",z)}if(m.setState(g),Y(g,h),typeof window<"u"&&typeof document<"u")try{const S=g.fragment;w.enabled&&S&&E(String(S),w.offset,w.timeoutMs).catch(()=>{})}catch{}}catch(e){if(c.devError("Navigation error:",e),e instanceof Error&&(e.stack?.includes("runBeforeEnter")||e.stack?.includes("runOnEnter")))throw e;try{const n=m.getState();if(!K(r,n.path).route){let g=r.find(b=>b.path==="/");if(g||(g=r.find(b=>!b.path.includes(":")&&!b.path.includes("*"))),!g&&r.length>0&&(g=r[0]),g){const b=K(r,g.path);m.setState({path:g.path,params:b.params,query:{}})}else c.devError("No fallback route available for error recovery")}}catch(n){c.devWarn("State recovery failed during navigation error:",n)}}};if((s=>{if(!s||s.length===0)return c.devError("Router configuration error: No routes provided"),!1;const f=new Set;for(const e of s){if(!e.path)return c.devError("Router configuration error: Route missing path",e),!1;f.has(e.path)&&c.devWarn(`Duplicate route path detected: ${e.path}`),f.add(e.path),!e.component&&!e.load&&c.devWarn(`Route '${e.path}' has no component or load function`)}return!0})(r),typeof window>"u"||typeof a<"u"){for(const s of r)O(s.path);c.devWarn(`Pre-compiled ${r.length} routes for SSR`)}if(typeof window<"u"&&typeof document<"u"&&typeof a>"u"){l=()=>{try{const e=new URL(window.location.href),n=e.pathname,h=n.startsWith(o)?n.slice(o.length):n,g=A(h||"/"),b=et(e.search),$=e.hash&&e.hash.length?e.hash.slice(1):"";return{path:g,query:b,fragment:$}}catch(e){return c.devWarn("Invalid URL detected, falling back to safe defaults",e),{path:"/",query:{},fragment:""}}},u=l();const s=O(u.path);m=ct.createStore({path:u.path,params:s.params,query:u.query,fragment:u.fragment}),P=async(e=!1)=>{const n=l();await q(n.path,e)};const f=()=>P(!0);window.addEventListener("popstate",f),J=()=>window.removeEventListener("popstate",f),W=e=>q(e,!1),L=e=>q(e,!0),H=()=>window.history.back()}else{l=()=>{try{const e=new URL(a||"/","http://localhost"),n=e.pathname,h=n.startsWith(o)?n.slice(o.length):n,g=A(h||"/"),b=et(e.search),$=e.hash&&e.hash.length?e.hash.slice(1):"";return{path:g,query:b,fragment:$}}catch(e){return c.devWarn("Invalid SSR URL detected, falling back to safe defaults",e),{path:"/",query:{},fragment:""}}},u=l();const s=O(u.path);m=ct.createStore({path:u.path,params:s.params,query:u.query,fragment:u.fragment}),P=async()=>{const e=l();await f(e.path)};const f=async e=>{if(k++,k>F){c.devError(`SSR redirect depth exceeded for path: ${e}`);return}try{const n=M(e),h=O(n.path);if(!h.route)throw new Error(`No route found for ${n.path}`);const g=m.getState(),b={path:n.path,params:h.params,query:n.query,fragment:n.fragment},$=Z(r,b.path);if($?.beforeEnter){const S=await $.beforeEnter(b,g);if(typeof S=="string"){const z=`${b.path}->${S}`;_.add(z),await f(S);return}if(S===!1)return}if($?.onEnter){const S=await $.onEnter(b,g);if(typeof S=="string"){const z=`${b.path}->${S}`;_.add(z),await f(S);return}if(S===!1)return}m.setState(b),$?.afterEnter&&$.afterEnter(b,g)}catch(n){throw c.devError("SSR navigation error:",n),n}};W=async e=>(k=0,_.clear(),f(e)),L=async e=>(k=0,_.clear(),f(e)),H=()=>{}}return{_cleanupScrollState:tt,destroy:J,store:m,push:W,replace:L,back:H,subscribe:m.subscribe,matchRoute:s=>O(s),getCurrent:()=>m.getState(),resolveRouteComponent:vt,base:o,scrollToFragment:s=>{const f=s||m.getState().fragment;return!f||typeof window>"u"||typeof document>"u"?Promise.resolve(!1):E(f,w.offset,w.timeoutMs)}}}function Wt(t){mt();const r=bt(t),y=ut();if(y){try{y.destroy()}catch{}try{y._cleanupScrollState?.()}catch{}}At(r);try{Pt();try{typeof window<"u"&&R.flushDOMUpdates()}catch{}try{typeof window<"u"&&queueMicrotask(()=>{try{R.flushDOMUpdates()}catch{}})}catch{}}catch{}return D.component("router-view",async()=>{if(!ut())return D.html`<div>Router not initialized.</div>`;const a=R.ref(C.getCurrent()),i=typeof window>"u";let o;i||(R.useOnConnected(()=>{try{typeof C.subscribe=="function"&&(o=C.subscribe(l=>{try{l&&typeof l=="object"&&typeof l.path=="string"?a.value=l:(c.devWarn("router-view received invalid state",l),a.value={path:"/",params:{},query:{}})}catch(u){c.devWarn("router-view subscription update failed",u);try{a.value={path:"/",params:{},query:{}}}catch{}}}))}catch(l){c.devWarn("router-view subscribe failed",l)}}),R.useOnDisconnected(()=>{if(typeof o=="function"){try{o()}catch(l){c.devWarn("router-view unsubscribe failed",l)}o=void 0}}));const w=C.matchRoute(a.value.path);if(!w||!w.route)return D.html`<div>Not found</div>`;try{const u=await C.resolveRouteComponent(w.route);if(typeof u=="string")return{tag:u,props:{},children:[]};if(typeof u=="function"){const m=u();return(m instanceof Promise?m:Promise.resolve(m)).then(W=>typeof W=="string"?{tag:W,props:{},children:[]}:W)}return D.html`<div>Invalid route component</div>`}catch{return D.html`<div>Invalid route component</div>`}}),D.component("router-link",()=>{const a=R.useProps({to:"",tag:"a",replace:!1,exact:!1,activeClass:"active",exactActiveClass:"exact-active",ariaCurrentValue:"page",disabled:!1,external:!1,class:"",style:""}),i=typeof window>"u",o=R.ref(C.getCurrent()),w=o.value?.path||"/",l=String(a.to||""),u=i?{isExactActive:ft(w,l,C.base),isActive:dt(w,l,C.base),isExternal:B(l)||!!a.external}:null;let m;R.useStyle(()=>"a,button{display:inline-block;}");const P=R.ref(a.class||""),W=R.ref(a.style||"");if(!i){let p=null;R.useOnConnected(E=>{try{if(typeof C.subscribe=="function"){m=C.subscribe(d=>{try{d&&typeof d=="object"&&typeof d.path=="string"?o.value=d:(c.devWarn("router-link received invalid state",d),o.value={path:"/",params:{},query:{}})}catch(q){c.devWarn("router-link subscription update failed",q);try{o.value={path:"/",params:{},query:{}}}catch{}}});try{const d=C.getCurrent();d&&typeof d.path=="string"&&(o.value=d)}catch(d){c.devWarn("router-link initial state sync failed",d)}p=setInterval(()=>{try{const d=C.getCurrent();d&&typeof d.path=="string"&&JSON.stringify(o.value)!==JSON.stringify(d)&&(o.value=d)}catch{}},100)}}catch(d){c.devWarn("router-link subscribe failed",d)}try{const d=E?._host;if(d instanceof HTMLElement){const q=d.getAttribute("class"),M=d.getAttribute("style");q&&(P.value=q),M&&(W.value=M),q!==null&&d.removeAttribute("class"),M!==null&&d.removeAttribute("style");try{E?._requestRender?.();try{R.flushDOMUpdates()}catch{}}catch{}}}catch(d){c.devWarn("router-link host migration failed",d)}}),R.useOnDisconnected(()=>{if(typeof m=="function")try{m()}catch(E){c.devWarn("router-link unsubscribe failed",E)}finally{m=void 0}if(p)try{clearInterval(p)}catch(E){c.devWarn("router-link sync interval cleanup failed",E)}finally{p=null}})}const L=R.computed(()=>{if(i&&u)return u.isExactActive;try{const p=C.base??"",E=a.to||"";return!o.value||typeof o.value.path!="string"?!1:ft(o.value.path,E,p)}catch(p){return c.devWarn("isExactActive computation error",p),!1}}),H=R.computed(()=>{if(i&&u)return u.isActive;try{const p=C.base??"",E=a.to||"";return!o.value||typeof o.value.path!="string"?!1:a.exact?L.value:dt(o.value.path,E,p)}catch(p){return c.devWarn("isActive computation error",p),!1}}),J=R.computed(()=>{const p=String(a.to||"");if(ot(p))return null;if(B(p))return p;const[E,d]=p.split("#"),[q,M]=(E||"").split("?"),N=C.base??"";let Q=q||"/";if(N&&N!=="/"){const nt=A(N),s=A(Q);s.startsWith(nt)?Q=s.slice(nt.length)||"/":Q=s}const st=A(Q||"/");return N+st+(M?"?"+M:"")+(d?"#"+d:"")}),_=R.computed(()=>{const E=(P&&P.value||a.class||"").split(/\s+/).filter(Boolean),d={};for(const q of E)d[q]=!0;return d}),F=R.computed(()=>({..._.value,[a.activeClass||"active"]:H.value,[a.exactActiveClass||"exact-active"]:L.value})),k=R.computed(()=>Object.keys(F.value).filter(p=>F.value[p]).join(" ")),X=R.computed(()=>a.tag||"a"),rt=R.computed(()=>X.value==="button"),Y=R.computed(()=>L.value?a.ariaCurrentValue:null),x=R.computed(()=>!!a.disabled),U=R.computed(()=>{const p=String(a.to||"");return(B(p)||!!a.external)&&X.value==="a"}),O=R.computed(()=>W&&W.value||a.style||""),tt=p=>{if(p.defaultPrevented||p.button!==0||p.metaKey||p.altKey||p.ctrlKey||p.shiftKey)return;if(x.value){p.preventDefault();return}const E=String(a.to||"");if(ot(E)){try{p.preventDefault()}catch{}c.devWarn("Blocked unsafe javascript: URI in router-link.to");return}U.value||(p.preventDefault(),a.replace?C.replace(a.to):C.push(a.to))};return D.html`
|
|
2
2
|
${St.match().when(rt.value,D.html`
|
|
3
3
|
<button
|
|
4
4
|
part="button"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as g, d as q } from "./logger-BvkEbVM4.js";
|
|
2
|
-
import { j as nt, r as et, w as it, x as lt, b as St, z as Rt, d as I } from "./hooks-
|
|
3
|
-
import { c as ut, h as U } from "./template-compiler-
|
|
2
|
+
import { j as nt, r as et, w as it, x as lt, b as St, z as Rt, d as I } from "./hooks-xWZhQHco.js";
|
|
3
|
+
import { c as ut, h as U } from "./template-compiler-ZhSg1yPh.js";
|
|
4
4
|
import { createStore as ft } from "./custom-elements-runtime.store.es.js";
|
|
5
5
|
import { match as $t } from "./custom-elements-runtime.directives.es.js";
|
|
6
6
|
const ht = {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("./custom-elements-runtime.ssr.cjs.js");function
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("./custom-elements-runtime.ssr.cjs.js");function y(e,n,o){if(!o)return e;if(e.trimStart().toLowerCase().startsWith("<html")||e.includes("</html>")){const r=n??"",a=e.startsWith("<!DOCTYPE")?e:`<!DOCTYPE html>${e}`;return r&&a.includes("</head>")?a.replace("</head>",`${r}</head>`):a}return`<!DOCTYPE html><html><head>${n??""}</head><body>${e}</body></html>`}function S(e,n){const o={dsd:!0,...n?.render},{head:c,document:r=!0}=n??{};return async(a,t)=>{try{const d=typeof e=="function"?await e(a):e,{htmlWithStyles:l}=m.renderToStringWithJITCSS(d,o),s=y(l,c,r);t.setHeader("Content-Type","text/html; charset=utf-8"),t.end(s)}catch(d){try{t.setHeader("Content-Type","text/plain; charset=utf-8"),t.end("Internal Server Error")}catch{}throw d}}}function T(e,n){const o={dsd:!0,...n?.render},{head:c,document:r=!0}=n??{};return async(a,t)=>{try{const d=typeof e=="function"?await e(a):e;t.setHeader("Content-Type","text/html; charset=utf-8");const s=m.renderToStream(d,o).getReader();if(t.write){t.setHeader("Transfer-Encoding","chunked"),r&&t.write(`<!DOCTYPE html><html><head>${c??""}</head><body>`);let h=!1;for(;!h;){const{value:i,done:u}=await s.read();i&&t.write(i),h=u}r?t.end("</body></html>"):t.end()}else{const h=[];let i=!1;for(;!i;){const{value:f,done:p}=await s.read();f&&h.push(f),i=p}const u=h.join(""),w=r?`<!DOCTYPE html><html><head>${c??""}</head><body>${u}</body></html>`:u;t.end(w)}}catch(d){try{t.setHeader("Content-Type","text/plain; charset=utf-8"),t.end("Internal Server Error")}catch{}throw d}}}exports.createSSRHandler=S;exports.createStreamingSSRHandler=T;
|
|
2
2
|
//# sourceMappingURL=custom-elements-runtime.ssr-middleware.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-elements-runtime.ssr-middleware.cjs.js","sources":["../src/lib/ssr-middleware.ts"],"sourcesContent":["/**\n * SSR middleware helpers for Express, Fastify, Hono, and other Node.js HTTP frameworks.\n *\n * Provides two handler factories that wrap the SSR rendering pipeline and\n * emit a complete HTML document response. Both accept a static VNode **or**\n * a per-request factory function so route-specific data can be threaded into\n * the render tree.\n *\n * @example Express — static VNode\n * ```ts\n * import express from 'express';\n * import { createSSRHandler } from '@jasonshimmy/custom-elements-runtime/ssr-middleware';\n * import { html } from '@jasonshimmy/custom-elements-runtime';\n *\n * const app = express();\n * app.get('/', createSSRHandler(html`<my-app />`, {\n * render: { dsd: true, jit: { extendedColors: true } },\n * }));\n * ```\n *\n * @example Express — per-request factory\n * ```ts\n * app.get('*', createSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * { render: { dsd: true }, head: '<link rel=\"stylesheet\" href=\"/app.css\">' },\n * ));\n * ```\n *\n * @example Streaming variant\n * ```ts\n * app.get('*', createStreamingSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * ));\n * ```\n */\n\nimport { renderToStringWithJITCSS, renderToStream } from './ssr';\nimport type { VNode } from './runtime/types';\nimport type { RenderOptions } from './runtime/vdom-ssr';\nimport type { DSDRenderOptions } from './runtime/vdom-ssr-dsd';\nimport type { JITCSSOptions } from './runtime/style';\n\n// ---------------------------------------------------------------------------\n// Minimal framework-agnostic HTTP types\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal request interface compatible with Express, Fastify, Hono, and the\n * raw Node.js `IncomingMessage`. Extend or replace with your framework's\n * request type via the generic parameter on `createSSRHandler`.\n */\nexport interface MinimalRequest {\n url?: string;\n method?: string;\n headers?: Record<string, string | string[] | undefined>;\n}\n\n/**\n * Minimal response interface compatible with Express, Fastify, Hono, and the\n * raw Node.js `ServerResponse`. `write` is optional — handlers fall back to\n * buffering when it is absent.\n */\nexport interface MinimalResponse {\n setHeader(name: string, value: string): void;\n write?(chunk: string): boolean | void;\n end(data?: string): void;\n}\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/**\n * Options for {@link createSSRHandler} and {@link createStreamingSSRHandler}.\n */\nexport interface SSRMiddlewareOptions {\n /**\n * Render options forwarded to `renderToStringWithJITCSS`.\n * Defaults to `{ dsd: true }` so DSD output is on by default.\n */\n render?: RenderOptions & DSDRenderOptions & { jit?: JITCSSOptions };\n /**\n * Additional HTML inserted at the end of the `<head>` tag.\n * Use this to inject `<link>`, `<script>`, `<meta>`, or `<title>` tags.\n */\n head?: string;\n /**\n * When `true` (default), the response is wrapped in a complete\n * `<!DOCTYPE html>` document shell. Set to `false` if you want to\n * assemble the document yourself and only need the rendered fragment.\n */\n document?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction wrapInDocument(\n htmlWithStyles: string,\n head: string | undefined,\n wrapDocument: boolean,\n): string {\n if (!wrapDocument) return htmlWithStyles;\n\n // If the rendered HTML already contains a root <html> tag, inject extra\n // head tags and prepend the DOCTYPE — do not double-wrap.\n if (\n htmlWithStyles.trimStart().toLowerCase().startsWith('<html') ||\n htmlWithStyles.includes('</html>')\n ) {\n const extra = head ?? '';\n const withDoctype = htmlWithStyles.startsWith('<!DOCTYPE')\n ? htmlWithStyles\n : `<!DOCTYPE html>${htmlWithStyles}`;\n if (extra) {\n return withDoctype.includes('</head>')\n ? withDoctype.replace('</head>', `${extra}</head>`)\n : withDoctype;\n }\n return withDoctype;\n }\n\n // Minimal shell\n const headContent = head ?? '';\n return `<!DOCTYPE html><html><head>${headContent}</head><body>${htmlWithStyles}</body></html>`;\n}\n\n// ---------------------------------------------------------------------------\n// Handler factories\n// ---------------------------------------------------------------------------\n\n/**\n * Create a request handler that SSR-renders a VNode tree and sends the full\n * HTML document as the response.\n *\n * Compatible with Express, Fastify, Hono, and any framework that uses an\n * `(req, res)` handler signature. The generic `Req` parameter lets you use\n * your framework's typed request object.\n *\n * @param vnodeOrFactory - A static {@link VNode} **or** a (possibly async)\n * factory function that receives the request and returns the VNode to render.\n * @param options - Render and document-shell options.\n *\n * @example\n * ```ts\n * app.get('*', createSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * { render: { dsd: true, jit: { extendedColors: true } } },\n * ));\n * ```\n */\nexport function createSSRHandler<Req extends MinimalRequest = MinimalRequest>(\n vnodeOrFactory: VNode | ((req: Req) => VNode | Promise<VNode>),\n options?: SSRMiddlewareOptions,\n): (req: Req, res: MinimalResponse) => Promise<void> {\n const renderOptions: RenderOptions &\n DSDRenderOptions & { jit?: JITCSSOptions } = {\n dsd: true,\n ...options?.render,\n };\n const { head, document: wrapDocument = true } = options ?? {};\n\n return async (req, res) => {\n try {\n const vnode =\n typeof vnodeOrFactory === 'function'\n ? await vnodeOrFactory(req)\n : vnodeOrFactory;\n\n const { htmlWithStyles } = renderToStringWithJITCSS(vnode, renderOptions);\n\n const body = wrapInDocument(htmlWithStyles, head, wrapDocument);\n\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n res.end(body);\n } catch (err) {\n // Ensure the response is always closed to prevent the request hanging.\n // Re-throw so the framework's error handler can set the proper status code.\n try {\n res.setHeader('Content-Type', 'text/plain; charset=utf-8');\n res.end('Internal Server Error');\n } catch {\n // ignore secondary errors during error response\n }\n throw err;\n }\n };\n}\n\n/**\n * Create a request handler that SSR-renders a VNode tree and streams the HTML\n * response using chunked transfer encoding.\n *\n * Each chunk produced by the underlying {@link renderToStream} call is written\n * to the response as it becomes available, minimising Time-to-First-Byte.\n * The document shell preamble (`<!DOCTYPE html>…<body>`) is sent in the first\n * write so the browser can begin parsing immediately.\n *\n * @param vnodeOrFactory - A static {@link VNode} **or** a (possibly async)\n * factory function that receives the request and returns the VNode to render.\n * @param options - Render and document-shell options.\n *\n * @example\n * ```ts\n * app.get('*', createStreamingSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * { render: { dsd: true } },\n * ));\n * ```\n */\nexport function createStreamingSSRHandler<\n Req extends MinimalRequest = MinimalRequest,\n>(\n vnodeOrFactory: VNode | ((req: Req) => VNode | Promise<VNode>),\n options?: SSRMiddlewareOptions,\n): (req: Req, res: MinimalResponse) => Promise<void> {\n const renderOptions: RenderOptions &\n DSDRenderOptions & { jit?: JITCSSOptions } = {\n dsd: true,\n ...options?.render,\n };\n const { head, document: wrapDocument = true } = options ?? {};\n\n return async (req, res) => {\n try {\n const vnode =\n typeof vnodeOrFactory === 'function'\n ? await vnodeOrFactory(req)\n : vnodeOrFactory;\n\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n\n const stream = renderToStream(vnode, renderOptions);\n const reader = stream.getReader();\n const chunks: string[] = [];\n let done = false;\n\n while (!done) {\n const { value, done: d } = await reader.read();\n if (value) chunks.push(value);\n done = d;\n }\n\n const content = chunks.join('');\n\n if (res.write) {\n // Streaming path: set chunked encoding and write incrementally.\n res.setHeader('Transfer-Encoding', 'chunked');\n if (wrapDocument) {\n res.write(`<!DOCTYPE html><html><head>${head ?? ''}</head><body>`);\n }\n res.write(content);\n if (wrapDocument) {\n res.end('</body></html>');\n } else {\n res.end();\n }\n } else {\n // Buffered fallback: framework does not expose write(); send as one response.\n const body = wrapDocument\n ? `<!DOCTYPE html><html><head>${head ?? ''}</head><body>${content}</body></html>`\n : content;\n res.end(body);\n }\n } catch (err) {\n // Ensure the response is always closed to prevent the request hanging.\n // Re-throw so the framework's error handler can set the proper status code.\n try {\n res.setHeader('Content-Type', 'text/plain; charset=utf-8');\n res.end('Internal Server Error');\n } catch {\n // ignore secondary errors during error response\n }\n throw err;\n }\n };\n}\n"],"names":["wrapInDocument","htmlWithStyles","head","wrapDocument","extra","withDoctype","createSSRHandler","vnodeOrFactory","options","renderOptions","req","res","vnode","renderToStringWithJITCSS","body","err","createStreamingSSRHandler","reader","renderToStream","chunks","done","value","d","content"],"mappings":"wIAkGA,SAASA,EACPC,EACAC,EACAC,EACQ,CACR,GAAI,CAACA,EAAc,OAAOF,EAI1B,GACEA,EAAe,YAAY,cAAc,WAAW,OAAO,GAC3DA,EAAe,SAAS,SAAS,EACjC,CACA,MAAMG,EAAQF,GAAQ,GAChBG,EAAcJ,EAAe,WAAW,WAAW,EACrDA,EACA,kBAAkBA,CAAc,GACpC,OAAIG,GACKC,EAAY,SAAS,SAAS,EACjCA,EAAY,QAAQ,UAAW,GAAGD,CAAK,SAAS,EAG/CC,CACT,CAIA,MAAO,8BADaH,GAAQ,EACoB,gBAAgBD,CAAc,gBAChF,CA0BO,SAASK,EACdC,EACAC,EACmD,CACnD,MAAMC,EACyC,CAC7C,IAAK,GACL,GAAGD,GAAS,MAAA,EAER,CAAE,KAAAN,EAAM,SAAUC,EAAe,EAAA,EAASK,GAAW,CAAA,EAE3D,MAAO,OAAOE,EAAKC,IAAQ,CACzB,GAAI,CACF,MAAMC,EACJ,OAAOL,GAAmB,WACtB,MAAMA,EAAeG,CAAG,EACxBH,EAEA,CAAE,eAAAN,CAAA,EAAmBY,2BAAyBD,EAAOH,CAAa,EAElEK,EAAOd,EAAeC,EAAgBC,EAAMC,CAAY,EAE9DQ,EAAI,UAAU,eAAgB,0BAA0B,EACxDA,EAAI,IAAIG,CAAI,CACd,OAASC,EAAK,CAGZ,GAAI,CACFJ,EAAI,UAAU,eAAgB,2BAA2B,EACzDA,EAAI,IAAI,uBAAuB,CACjC,MAAQ,CAER,CACA,MAAMI,CACR,CACF,CACF,CAuBO,SAASC,EAGdT,EACAC,EACmD,CACnD,MAAMC,EACyC,CAC7C,IAAK,GACL,GAAGD,GAAS,MAAA,EAER,CAAE,KAAAN,EAAM,SAAUC,EAAe,EAAA,EAASK,GAAW,CAAA,EAE3D,MAAO,OAAOE,EAAKC,IAAQ,CACzB,GAAI,CACF,MAAMC,EACJ,OAAOL,GAAmB,WACtB,MAAMA,EAAeG,CAAG,EACxBH,EAENI,EAAI,UAAU,eAAgB,0BAA0B,EAGxD,MAAMM,EADSC,EAAAA,eAAeN,EAAOH,CAAa,EAC5B,UAAA,EAChBU,EAAmB,CAAA,EACzB,IAAIC,EAAO,GAEX,KAAO,CAACA,GAAM,CACZ,KAAM,CAAE,MAAAC,EAAO,KAAMC,GAAM,MAAML,EAAO,KAAA,EACpCI,GAAOF,EAAO,KAAKE,CAAK,EAC5BD,EAAOE,CACT,CAEA,MAAMC,EAAUJ,EAAO,KAAK,EAAE,EAE9B,GAAIR,EAAI,MAENA,EAAI,UAAU,oBAAqB,SAAS,EACxCR,GACFQ,EAAI,MAAM,8BAA8BT,GAAQ,EAAE,eAAe,EAEnES,EAAI,MAAMY,CAAO,EACbpB,EACFQ,EAAI,IAAI,gBAAgB,EAExBA,EAAI,IAAA,MAED,CAEL,MAAMG,EAAOX,EACT,8BAA8BD,GAAQ,EAAE,gBAAgBqB,CAAO,iBAC/DA,EACJZ,EAAI,IAAIG,CAAI,CACd,CACF,OAASC,EAAK,CAGZ,GAAI,CACFJ,EAAI,UAAU,eAAgB,2BAA2B,EACzDA,EAAI,IAAI,uBAAuB,CACjC,MAAQ,CAER,CACA,MAAMI,CACR,CACF,CACF"}
|
|
1
|
+
{"version":3,"file":"custom-elements-runtime.ssr-middleware.cjs.js","sources":["../src/lib/ssr-middleware.ts"],"sourcesContent":["/**\n * SSR middleware helpers for Express, Fastify, Hono, and other Node.js HTTP frameworks.\n *\n * Provides two handler factories that wrap the SSR rendering pipeline and\n * emit a complete HTML document response. Both accept a static VNode **or**\n * a per-request factory function so route-specific data can be threaded into\n * the render tree.\n *\n * @example Express — static VNode\n * ```ts\n * import express from 'express';\n * import { createSSRHandler } from '@jasonshimmy/custom-elements-runtime/ssr-middleware';\n * import { html } from '@jasonshimmy/custom-elements-runtime';\n *\n * const app = express();\n * app.get('/', createSSRHandler(html`<my-app />`, {\n * render: { dsd: true, jit: { extendedColors: true } },\n * }));\n * ```\n *\n * @example Express — per-request factory\n * ```ts\n * app.get('*', createSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * { render: { dsd: true }, head: '<link rel=\"stylesheet\" href=\"/app.css\">' },\n * ));\n * ```\n *\n * @example Streaming variant\n * ```ts\n * app.get('*', createStreamingSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * ));\n * ```\n */\n\nimport { renderToStringWithJITCSS, renderToStream } from './ssr';\nimport type { VNode } from './runtime/types';\nimport type { RenderOptions } from './runtime/vdom-ssr';\nimport type { DSDRenderOptions } from './runtime/vdom-ssr-dsd';\nimport type { JITCSSOptions } from './runtime/style';\n\n// ---------------------------------------------------------------------------\n// Minimal framework-agnostic HTTP types\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal request interface compatible with Express, Fastify, Hono, and the\n * raw Node.js `IncomingMessage`. Extend or replace with your framework's\n * request type via the generic parameter on `createSSRHandler`.\n */\nexport interface MinimalRequest {\n url?: string;\n method?: string;\n headers?: Record<string, string | string[] | undefined>;\n}\n\n/**\n * Minimal response interface compatible with Express, Fastify, Hono, and the\n * raw Node.js `ServerResponse`. `write` is optional — handlers fall back to\n * buffering when it is absent.\n */\nexport interface MinimalResponse {\n setHeader(name: string, value: string): void;\n write?(chunk: string): boolean | void;\n end(data?: string): void;\n}\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/**\n * Options for {@link createSSRHandler} and {@link createStreamingSSRHandler}.\n */\nexport interface SSRMiddlewareOptions {\n /**\n * Render options forwarded to `renderToStringWithJITCSS`.\n * Defaults to `{ dsd: true }` so DSD output is on by default.\n */\n render?: RenderOptions & DSDRenderOptions & { jit?: JITCSSOptions };\n /**\n * Additional HTML inserted at the end of the `<head>` tag.\n * Use this to inject `<link>`, `<script>`, `<meta>`, or `<title>` tags.\n */\n head?: string;\n /**\n * When `true` (default), the response is wrapped in a complete\n * `<!DOCTYPE html>` document shell. Set to `false` if you want to\n * assemble the document yourself and only need the rendered fragment.\n */\n document?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction wrapInDocument(\n htmlWithStyles: string,\n head: string | undefined,\n wrapDocument: boolean,\n): string {\n if (!wrapDocument) return htmlWithStyles;\n\n // If the rendered HTML already contains a root <html> tag, inject extra\n // head tags and prepend the DOCTYPE — do not double-wrap.\n if (\n htmlWithStyles.trimStart().toLowerCase().startsWith('<html') ||\n htmlWithStyles.includes('</html>')\n ) {\n const extra = head ?? '';\n const withDoctype = htmlWithStyles.startsWith('<!DOCTYPE')\n ? htmlWithStyles\n : `<!DOCTYPE html>${htmlWithStyles}`;\n if (extra) {\n return withDoctype.includes('</head>')\n ? withDoctype.replace('</head>', `${extra}</head>`)\n : withDoctype;\n }\n return withDoctype;\n }\n\n // Minimal shell\n const headContent = head ?? '';\n return `<!DOCTYPE html><html><head>${headContent}</head><body>${htmlWithStyles}</body></html>`;\n}\n\n// ---------------------------------------------------------------------------\n// Handler factories\n// ---------------------------------------------------------------------------\n\n/**\n * Create a request handler that SSR-renders a VNode tree and sends the full\n * HTML document as the response.\n *\n * Compatible with Express, Fastify, Hono, and any framework that uses an\n * `(req, res)` handler signature. The generic `Req` parameter lets you use\n * your framework's typed request object.\n *\n * @param vnodeOrFactory - A static {@link VNode} **or** a (possibly async)\n * factory function that receives the request and returns the VNode to render.\n * @param options - Render and document-shell options.\n *\n * @example\n * ```ts\n * app.get('*', createSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * { render: { dsd: true, jit: { extendedColors: true } } },\n * ));\n * ```\n */\nexport function createSSRHandler<Req extends MinimalRequest = MinimalRequest>(\n vnodeOrFactory: VNode | ((req: Req) => VNode | Promise<VNode>),\n options?: SSRMiddlewareOptions,\n): (req: Req, res: MinimalResponse) => Promise<void> {\n const renderOptions: RenderOptions &\n DSDRenderOptions & { jit?: JITCSSOptions } = {\n dsd: true,\n ...options?.render,\n };\n const { head, document: wrapDocument = true } = options ?? {};\n\n return async (req, res) => {\n try {\n const vnode =\n typeof vnodeOrFactory === 'function'\n ? await vnodeOrFactory(req)\n : vnodeOrFactory;\n\n const { htmlWithStyles } = renderToStringWithJITCSS(vnode, renderOptions);\n\n const body = wrapInDocument(htmlWithStyles, head, wrapDocument);\n\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n res.end(body);\n } catch (err) {\n // Ensure the response is always closed to prevent the request hanging.\n // Re-throw so the framework's error handler can set the proper status code.\n try {\n res.setHeader('Content-Type', 'text/plain; charset=utf-8');\n res.end('Internal Server Error');\n } catch {\n // ignore secondary errors during error response\n }\n throw err;\n }\n };\n}\n\n/**\n * Create a request handler that SSR-renders a VNode tree and streams the HTML\n * response using chunked transfer encoding.\n *\n * Each chunk produced by the underlying {@link renderToStream} call is written\n * to the response as it becomes available, minimising Time-to-First-Byte.\n * The document shell preamble (`<!DOCTYPE html>…<body>`) is sent in the first\n * write so the browser can begin parsing immediately.\n *\n * @param vnodeOrFactory - A static {@link VNode} **or** a (possibly async)\n * factory function that receives the request and returns the VNode to render.\n * @param options - Render and document-shell options.\n *\n * @example\n * ```ts\n * app.get('*', createStreamingSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * { render: { dsd: true } },\n * ));\n * ```\n */\nexport function createStreamingSSRHandler<\n Req extends MinimalRequest = MinimalRequest,\n>(\n vnodeOrFactory: VNode | ((req: Req) => VNode | Promise<VNode>),\n options?: SSRMiddlewareOptions,\n): (req: Req, res: MinimalResponse) => Promise<void> {\n const renderOptions: RenderOptions &\n DSDRenderOptions & { jit?: JITCSSOptions } = {\n dsd: true,\n ...options?.render,\n };\n const { head, document: wrapDocument = true } = options ?? {};\n\n return async (req, res) => {\n try {\n const vnode =\n typeof vnodeOrFactory === 'function'\n ? await vnodeOrFactory(req)\n : vnodeOrFactory;\n\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n\n const stream = renderToStream(vnode, renderOptions);\n const reader = stream.getReader();\n\n if (res.write) {\n // Streaming path: pipe chunks directly to the response as they arrive.\n res.setHeader('Transfer-Encoding', 'chunked');\n if (wrapDocument) {\n res.write(`<!DOCTYPE html><html><head>${head ?? ''}</head><body>`);\n }\n let done = false;\n while (!done) {\n const { value, done: d } = await reader.read();\n if (value) res.write(value);\n done = d;\n }\n if (wrapDocument) {\n res.end('</body></html>');\n } else {\n res.end();\n }\n } else {\n // Buffered fallback: framework does not expose write(); collect and send as one response.\n const chunks: string[] = [];\n let done = false;\n while (!done) {\n const { value, done: d } = await reader.read();\n if (value) chunks.push(value);\n done = d;\n }\n const content = chunks.join('');\n const body = wrapDocument\n ? `<!DOCTYPE html><html><head>${head ?? ''}</head><body>${content}</body></html>`\n : content;\n res.end(body);\n }\n } catch (err) {\n // Ensure the response is always closed to prevent the request hanging.\n // Re-throw so the framework's error handler can set the proper status code.\n try {\n res.setHeader('Content-Type', 'text/plain; charset=utf-8');\n res.end('Internal Server Error');\n } catch {\n // ignore secondary errors during error response\n }\n throw err;\n }\n };\n}\n"],"names":["wrapInDocument","htmlWithStyles","head","wrapDocument","extra","withDoctype","createSSRHandler","vnodeOrFactory","options","renderOptions","req","res","vnode","renderToStringWithJITCSS","body","err","createStreamingSSRHandler","reader","renderToStream","done","value","d","chunks","content"],"mappings":"wIAkGA,SAASA,EACPC,EACAC,EACAC,EACQ,CACR,GAAI,CAACA,EAAc,OAAOF,EAI1B,GACEA,EAAe,YAAY,cAAc,WAAW,OAAO,GAC3DA,EAAe,SAAS,SAAS,EACjC,CACA,MAAMG,EAAQF,GAAQ,GAChBG,EAAcJ,EAAe,WAAW,WAAW,EACrDA,EACA,kBAAkBA,CAAc,GACpC,OAAIG,GACKC,EAAY,SAAS,SAAS,EACjCA,EAAY,QAAQ,UAAW,GAAGD,CAAK,SAAS,EAG/CC,CACT,CAIA,MAAO,8BADaH,GAAQ,EACoB,gBAAgBD,CAAc,gBAChF,CA0BO,SAASK,EACdC,EACAC,EACmD,CACnD,MAAMC,EACyC,CAC7C,IAAK,GACL,GAAGD,GAAS,MAAA,EAER,CAAE,KAAAN,EAAM,SAAUC,EAAe,EAAA,EAASK,GAAW,CAAA,EAE3D,MAAO,OAAOE,EAAKC,IAAQ,CACzB,GAAI,CACF,MAAMC,EACJ,OAAOL,GAAmB,WACtB,MAAMA,EAAeG,CAAG,EACxBH,EAEA,CAAE,eAAAN,CAAA,EAAmBY,2BAAyBD,EAAOH,CAAa,EAElEK,EAAOd,EAAeC,EAAgBC,EAAMC,CAAY,EAE9DQ,EAAI,UAAU,eAAgB,0BAA0B,EACxDA,EAAI,IAAIG,CAAI,CACd,OAASC,EAAK,CAGZ,GAAI,CACFJ,EAAI,UAAU,eAAgB,2BAA2B,EACzDA,EAAI,IAAI,uBAAuB,CACjC,MAAQ,CAER,CACA,MAAMI,CACR,CACF,CACF,CAuBO,SAASC,EAGdT,EACAC,EACmD,CACnD,MAAMC,EACyC,CAC7C,IAAK,GACL,GAAGD,GAAS,MAAA,EAER,CAAE,KAAAN,EAAM,SAAUC,EAAe,EAAA,EAASK,GAAW,CAAA,EAE3D,MAAO,OAAOE,EAAKC,IAAQ,CACzB,GAAI,CACF,MAAMC,EACJ,OAAOL,GAAmB,WACtB,MAAMA,EAAeG,CAAG,EACxBH,EAENI,EAAI,UAAU,eAAgB,0BAA0B,EAGxD,MAAMM,EADSC,EAAAA,eAAeN,EAAOH,CAAa,EAC5B,UAAA,EAEtB,GAAIE,EAAI,MAAO,CAEbA,EAAI,UAAU,oBAAqB,SAAS,EACxCR,GACFQ,EAAI,MAAM,8BAA8BT,GAAQ,EAAE,eAAe,EAEnE,IAAIiB,EAAO,GACX,KAAO,CAACA,GAAM,CACZ,KAAM,CAAE,MAAAC,EAAO,KAAMC,GAAM,MAAMJ,EAAO,KAAA,EACpCG,GAAOT,EAAI,MAAMS,CAAK,EAC1BD,EAAOE,CACT,CACIlB,EACFQ,EAAI,IAAI,gBAAgB,EAExBA,EAAI,IAAA,CAER,KAAO,CAEL,MAAMW,EAAmB,CAAA,EACzB,IAAIH,EAAO,GACX,KAAO,CAACA,GAAM,CACZ,KAAM,CAAE,MAAAC,EAAO,KAAMC,GAAM,MAAMJ,EAAO,KAAA,EACpCG,GAAOE,EAAO,KAAKF,CAAK,EAC5BD,EAAOE,CACT,CACA,MAAME,EAAUD,EAAO,KAAK,EAAE,EACxBR,EAAOX,EACT,8BAA8BD,GAAQ,EAAE,gBAAgBqB,CAAO,iBAC/DA,EACJZ,EAAI,IAAIG,CAAI,CACd,CACF,OAASC,EAAK,CAGZ,GAAI,CACFJ,EAAI,UAAU,eAAgB,2BAA2B,EACzDA,EAAI,IAAI,uBAAuB,CACjC,MAAQ,CAER,CACA,MAAMI,CACR,CACF,CACF"}
|
|
@@ -1,55 +1,61 @@
|
|
|
1
|
-
import { renderToStringWithJITCSS as
|
|
2
|
-
function
|
|
3
|
-
if (!o) return
|
|
4
|
-
if (
|
|
5
|
-
const r = n ?? "", a =
|
|
1
|
+
import { renderToStringWithJITCSS as w, renderToStream as C } from "./custom-elements-runtime.ssr.es.js";
|
|
2
|
+
function T(e, n, o) {
|
|
3
|
+
if (!o) return e;
|
|
4
|
+
if (e.trimStart().toLowerCase().startsWith("<html") || e.includes("</html>")) {
|
|
5
|
+
const r = n ?? "", a = e.startsWith("<!DOCTYPE") ? e : `<!DOCTYPE html>${e}`;
|
|
6
6
|
return r && a.includes("</head>") ? a.replace("</head>", `${r}</head>`) : a;
|
|
7
7
|
}
|
|
8
|
-
return `<!DOCTYPE html><html><head>${n ?? ""}</head><body>${
|
|
8
|
+
return `<!DOCTYPE html><html><head>${n ?? ""}</head><body>${e}</body></html>`;
|
|
9
9
|
}
|
|
10
|
-
function
|
|
10
|
+
function D(e, n) {
|
|
11
11
|
const o = {
|
|
12
12
|
dsd: !0,
|
|
13
13
|
...n?.render
|
|
14
14
|
}, { head: c, document: r = !0 } = n ?? {};
|
|
15
|
-
return async (a,
|
|
15
|
+
return async (a, t) => {
|
|
16
16
|
try {
|
|
17
|
-
const d = typeof
|
|
18
|
-
|
|
17
|
+
const d = typeof e == "function" ? await e(a) : e, { htmlWithStyles: f } = w(d, o), u = T(f, c, r);
|
|
18
|
+
t.setHeader("Content-Type", "text/html; charset=utf-8"), t.end(u);
|
|
19
19
|
} catch (d) {
|
|
20
20
|
try {
|
|
21
|
-
|
|
21
|
+
t.setHeader("Content-Type", "text/plain; charset=utf-8"), t.end("Internal Server Error");
|
|
22
22
|
} catch {
|
|
23
23
|
}
|
|
24
24
|
throw d;
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
function
|
|
28
|
+
function b(e, n) {
|
|
29
29
|
const o = {
|
|
30
30
|
dsd: !0,
|
|
31
31
|
...n?.render
|
|
32
32
|
}, { head: c, document: r = !0 } = n ?? {};
|
|
33
|
-
return async (a,
|
|
33
|
+
return async (a, t) => {
|
|
34
34
|
try {
|
|
35
|
-
const d = typeof
|
|
36
|
-
|
|
37
|
-
const u =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
else {
|
|
47
|
-
const h =
|
|
48
|
-
|
|
35
|
+
const d = typeof e == "function" ? await e(a) : e;
|
|
36
|
+
t.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
37
|
+
const u = C(d, o).getReader();
|
|
38
|
+
if (t.write) {
|
|
39
|
+
t.setHeader("Transfer-Encoding", "chunked"), r && t.write(`<!DOCTYPE html><html><head>${c ?? ""}</head><body>`);
|
|
40
|
+
let h = !1;
|
|
41
|
+
for (; !h; ) {
|
|
42
|
+
const { value: i, done: s } = await u.read();
|
|
43
|
+
i && t.write(i), h = s;
|
|
44
|
+
}
|
|
45
|
+
r ? t.end("</body></html>") : t.end();
|
|
46
|
+
} else {
|
|
47
|
+
const h = [];
|
|
48
|
+
let i = !1;
|
|
49
|
+
for (; !i; ) {
|
|
50
|
+
const { value: l, done: p } = await u.read();
|
|
51
|
+
l && h.push(l), i = p;
|
|
52
|
+
}
|
|
53
|
+
const s = h.join(""), m = r ? `<!DOCTYPE html><html><head>${c ?? ""}</head><body>${s}</body></html>` : s;
|
|
54
|
+
t.end(m);
|
|
49
55
|
}
|
|
50
56
|
} catch (d) {
|
|
51
57
|
try {
|
|
52
|
-
|
|
58
|
+
t.setHeader("Content-Type", "text/plain; charset=utf-8"), t.end("Internal Server Error");
|
|
53
59
|
} catch {
|
|
54
60
|
}
|
|
55
61
|
throw d;
|
|
@@ -57,7 +63,7 @@ function D(t, n) {
|
|
|
57
63
|
};
|
|
58
64
|
}
|
|
59
65
|
export {
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
D as createSSRHandler,
|
|
67
|
+
b as createStreamingSSRHandler
|
|
62
68
|
};
|
|
63
69
|
//# sourceMappingURL=custom-elements-runtime.ssr-middleware.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-elements-runtime.ssr-middleware.es.js","sources":["../src/lib/ssr-middleware.ts"],"sourcesContent":["/**\n * SSR middleware helpers for Express, Fastify, Hono, and other Node.js HTTP frameworks.\n *\n * Provides two handler factories that wrap the SSR rendering pipeline and\n * emit a complete HTML document response. Both accept a static VNode **or**\n * a per-request factory function so route-specific data can be threaded into\n * the render tree.\n *\n * @example Express — static VNode\n * ```ts\n * import express from 'express';\n * import { createSSRHandler } from '@jasonshimmy/custom-elements-runtime/ssr-middleware';\n * import { html } from '@jasonshimmy/custom-elements-runtime';\n *\n * const app = express();\n * app.get('/', createSSRHandler(html`<my-app />`, {\n * render: { dsd: true, jit: { extendedColors: true } },\n * }));\n * ```\n *\n * @example Express — per-request factory\n * ```ts\n * app.get('*', createSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * { render: { dsd: true }, head: '<link rel=\"stylesheet\" href=\"/app.css\">' },\n * ));\n * ```\n *\n * @example Streaming variant\n * ```ts\n * app.get('*', createStreamingSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * ));\n * ```\n */\n\nimport { renderToStringWithJITCSS, renderToStream } from './ssr';\nimport type { VNode } from './runtime/types';\nimport type { RenderOptions } from './runtime/vdom-ssr';\nimport type { DSDRenderOptions } from './runtime/vdom-ssr-dsd';\nimport type { JITCSSOptions } from './runtime/style';\n\n// ---------------------------------------------------------------------------\n// Minimal framework-agnostic HTTP types\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal request interface compatible with Express, Fastify, Hono, and the\n * raw Node.js `IncomingMessage`. Extend or replace with your framework's\n * request type via the generic parameter on `createSSRHandler`.\n */\nexport interface MinimalRequest {\n url?: string;\n method?: string;\n headers?: Record<string, string | string[] | undefined>;\n}\n\n/**\n * Minimal response interface compatible with Express, Fastify, Hono, and the\n * raw Node.js `ServerResponse`. `write` is optional — handlers fall back to\n * buffering when it is absent.\n */\nexport interface MinimalResponse {\n setHeader(name: string, value: string): void;\n write?(chunk: string): boolean | void;\n end(data?: string): void;\n}\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/**\n * Options for {@link createSSRHandler} and {@link createStreamingSSRHandler}.\n */\nexport interface SSRMiddlewareOptions {\n /**\n * Render options forwarded to `renderToStringWithJITCSS`.\n * Defaults to `{ dsd: true }` so DSD output is on by default.\n */\n render?: RenderOptions & DSDRenderOptions & { jit?: JITCSSOptions };\n /**\n * Additional HTML inserted at the end of the `<head>` tag.\n * Use this to inject `<link>`, `<script>`, `<meta>`, or `<title>` tags.\n */\n head?: string;\n /**\n * When `true` (default), the response is wrapped in a complete\n * `<!DOCTYPE html>` document shell. Set to `false` if you want to\n * assemble the document yourself and only need the rendered fragment.\n */\n document?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction wrapInDocument(\n htmlWithStyles: string,\n head: string | undefined,\n wrapDocument: boolean,\n): string {\n if (!wrapDocument) return htmlWithStyles;\n\n // If the rendered HTML already contains a root <html> tag, inject extra\n // head tags and prepend the DOCTYPE — do not double-wrap.\n if (\n htmlWithStyles.trimStart().toLowerCase().startsWith('<html') ||\n htmlWithStyles.includes('</html>')\n ) {\n const extra = head ?? '';\n const withDoctype = htmlWithStyles.startsWith('<!DOCTYPE')\n ? htmlWithStyles\n : `<!DOCTYPE html>${htmlWithStyles}`;\n if (extra) {\n return withDoctype.includes('</head>')\n ? withDoctype.replace('</head>', `${extra}</head>`)\n : withDoctype;\n }\n return withDoctype;\n }\n\n // Minimal shell\n const headContent = head ?? '';\n return `<!DOCTYPE html><html><head>${headContent}</head><body>${htmlWithStyles}</body></html>`;\n}\n\n// ---------------------------------------------------------------------------\n// Handler factories\n// ---------------------------------------------------------------------------\n\n/**\n * Create a request handler that SSR-renders a VNode tree and sends the full\n * HTML document as the response.\n *\n * Compatible with Express, Fastify, Hono, and any framework that uses an\n * `(req, res)` handler signature. The generic `Req` parameter lets you use\n * your framework's typed request object.\n *\n * @param vnodeOrFactory - A static {@link VNode} **or** a (possibly async)\n * factory function that receives the request and returns the VNode to render.\n * @param options - Render and document-shell options.\n *\n * @example\n * ```ts\n * app.get('*', createSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * { render: { dsd: true, jit: { extendedColors: true } } },\n * ));\n * ```\n */\nexport function createSSRHandler<Req extends MinimalRequest = MinimalRequest>(\n vnodeOrFactory: VNode | ((req: Req) => VNode | Promise<VNode>),\n options?: SSRMiddlewareOptions,\n): (req: Req, res: MinimalResponse) => Promise<void> {\n const renderOptions: RenderOptions &\n DSDRenderOptions & { jit?: JITCSSOptions } = {\n dsd: true,\n ...options?.render,\n };\n const { head, document: wrapDocument = true } = options ?? {};\n\n return async (req, res) => {\n try {\n const vnode =\n typeof vnodeOrFactory === 'function'\n ? await vnodeOrFactory(req)\n : vnodeOrFactory;\n\n const { htmlWithStyles } = renderToStringWithJITCSS(vnode, renderOptions);\n\n const body = wrapInDocument(htmlWithStyles, head, wrapDocument);\n\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n res.end(body);\n } catch (err) {\n // Ensure the response is always closed to prevent the request hanging.\n // Re-throw so the framework's error handler can set the proper status code.\n try {\n res.setHeader('Content-Type', 'text/plain; charset=utf-8');\n res.end('Internal Server Error');\n } catch {\n // ignore secondary errors during error response\n }\n throw err;\n }\n };\n}\n\n/**\n * Create a request handler that SSR-renders a VNode tree and streams the HTML\n * response using chunked transfer encoding.\n *\n * Each chunk produced by the underlying {@link renderToStream} call is written\n * to the response as it becomes available, minimising Time-to-First-Byte.\n * The document shell preamble (`<!DOCTYPE html>…<body>`) is sent in the first\n * write so the browser can begin parsing immediately.\n *\n * @param vnodeOrFactory - A static {@link VNode} **or** a (possibly async)\n * factory function that receives the request and returns the VNode to render.\n * @param options - Render and document-shell options.\n *\n * @example\n * ```ts\n * app.get('*', createStreamingSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * { render: { dsd: true } },\n * ));\n * ```\n */\nexport function createStreamingSSRHandler<\n Req extends MinimalRequest = MinimalRequest,\n>(\n vnodeOrFactory: VNode | ((req: Req) => VNode | Promise<VNode>),\n options?: SSRMiddlewareOptions,\n): (req: Req, res: MinimalResponse) => Promise<void> {\n const renderOptions: RenderOptions &\n DSDRenderOptions & { jit?: JITCSSOptions } = {\n dsd: true,\n ...options?.render,\n };\n const { head, document: wrapDocument = true } = options ?? {};\n\n return async (req, res) => {\n try {\n const vnode =\n typeof vnodeOrFactory === 'function'\n ? await vnodeOrFactory(req)\n : vnodeOrFactory;\n\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n\n const stream = renderToStream(vnode, renderOptions);\n const reader = stream.getReader();\n const chunks: string[] = [];\n let done = false;\n\n while (!done) {\n const { value, done: d } = await reader.read();\n if (value) chunks.push(value);\n done = d;\n }\n\n const content = chunks.join('');\n\n if (res.write) {\n // Streaming path: set chunked encoding and write incrementally.\n res.setHeader('Transfer-Encoding', 'chunked');\n if (wrapDocument) {\n res.write(`<!DOCTYPE html><html><head>${head ?? ''}</head><body>`);\n }\n res.write(content);\n if (wrapDocument) {\n res.end('</body></html>');\n } else {\n res.end();\n }\n } else {\n // Buffered fallback: framework does not expose write(); send as one response.\n const body = wrapDocument\n ? `<!DOCTYPE html><html><head>${head ?? ''}</head><body>${content}</body></html>`\n : content;\n res.end(body);\n }\n } catch (err) {\n // Ensure the response is always closed to prevent the request hanging.\n // Re-throw so the framework's error handler can set the proper status code.\n try {\n res.setHeader('Content-Type', 'text/plain; charset=utf-8');\n res.end('Internal Server Error');\n } catch {\n // ignore secondary errors during error response\n }\n throw err;\n }\n };\n}\n"],"names":["wrapInDocument","htmlWithStyles","head","wrapDocument","extra","withDoctype","createSSRHandler","vnodeOrFactory","options","renderOptions","req","res","vnode","renderToStringWithJITCSS","body","err","createStreamingSSRHandler","reader","renderToStream","chunks","done","value","d","content"],"mappings":";AAkGA,SAASA,EACPC,GACAC,GACAC,GACQ;AACR,MAAI,CAACA,EAAc,QAAOF;AAI1B,MACEA,EAAe,YAAY,cAAc,WAAW,OAAO,KAC3DA,EAAe,SAAS,SAAS,GACjC;AACA,UAAMG,IAAQF,KAAQ,IAChBG,IAAcJ,EAAe,WAAW,WAAW,IACrDA,IACA,kBAAkBA,CAAc;AACpC,WAAIG,KACKC,EAAY,SAAS,SAAS,IACjCA,EAAY,QAAQ,WAAW,GAAGD,CAAK,SAAS,IAG/CC;AAAA,EACT;AAIA,SAAO,8BADaH,KAAQ,EACoB,gBAAgBD,CAAc;AAChF;AA0BO,SAASK,EACdC,GACAC,GACmD;AACnD,QAAMC,IACyC;AAAA,IAC7C,KAAK;AAAA,IACL,GAAGD,GAAS;AAAA,EAAA,GAER,EAAE,MAAAN,GAAM,UAAUC,IAAe,GAAA,IAASK,KAAW,CAAA;AAE3D,SAAO,OAAOE,GAAKC,MAAQ;AACzB,QAAI;AACF,YAAMC,IACJ,OAAOL,KAAmB,aACtB,MAAMA,EAAeG,CAAG,IACxBH,GAEA,EAAE,gBAAAN,EAAA,IAAmBY,EAAyBD,GAAOH,CAAa,GAElEK,IAAOd,EAAeC,GAAgBC,GAAMC,CAAY;AAE9D,MAAAQ,EAAI,UAAU,gBAAgB,0BAA0B,GACxDA,EAAI,IAAIG,CAAI;AAAA,IACd,SAASC,GAAK;AAGZ,UAAI;AACF,QAAAJ,EAAI,UAAU,gBAAgB,2BAA2B,GACzDA,EAAI,IAAI,uBAAuB;AAAA,MACjC,QAAQ;AAAA,MAER;AACA,YAAMI;AAAA,IACR;AAAA,EACF;AACF;AAuBO,SAASC,EAGdT,GACAC,GACmD;AACnD,QAAMC,IACyC;AAAA,IAC7C,KAAK;AAAA,IACL,GAAGD,GAAS;AAAA,EAAA,GAER,EAAE,MAAAN,GAAM,UAAUC,IAAe,GAAA,IAASK,KAAW,CAAA;AAE3D,SAAO,OAAOE,GAAKC,MAAQ;AACzB,QAAI;AACF,YAAMC,IACJ,OAAOL,KAAmB,aACtB,MAAMA,EAAeG,CAAG,IACxBH;AAEN,MAAAI,EAAI,UAAU,gBAAgB,0BAA0B;AAGxD,YAAMM,IADSC,EAAeN,GAAOH,CAAa,EAC5B,UAAA,GAChBU,IAAmB,CAAA;AACzB,UAAIC,IAAO;AAEX,aAAO,CAACA,KAAM;AACZ,cAAM,EAAE,OAAAC,GAAO,MAAMC,MAAM,MAAML,EAAO,KAAA;AACxC,QAAII,KAAOF,EAAO,KAAKE,CAAK,GAC5BD,IAAOE;AAAA,MACT;AAEA,YAAMC,IAAUJ,EAAO,KAAK,EAAE;AAE9B,UAAIR,EAAI;AAEN,QAAAA,EAAI,UAAU,qBAAqB,SAAS,GACxCR,KACFQ,EAAI,MAAM,8BAA8BT,KAAQ,EAAE,eAAe,GAEnES,EAAI,MAAMY,CAAO,GACbpB,IACFQ,EAAI,IAAI,gBAAgB,IAExBA,EAAI,IAAA;AAAA,WAED;AAEL,cAAMG,IAAOX,IACT,8BAA8BD,KAAQ,EAAE,gBAAgBqB,CAAO,mBAC/DA;AACJ,QAAAZ,EAAI,IAAIG,CAAI;AAAA,MACd;AAAA,IACF,SAASC,GAAK;AAGZ,UAAI;AACF,QAAAJ,EAAI,UAAU,gBAAgB,2BAA2B,GACzDA,EAAI,IAAI,uBAAuB;AAAA,MACjC,QAAQ;AAAA,MAER;AACA,YAAMI;AAAA,IACR;AAAA,EACF;AACF;"}
|
|
1
|
+
{"version":3,"file":"custom-elements-runtime.ssr-middleware.es.js","sources":["../src/lib/ssr-middleware.ts"],"sourcesContent":["/**\n * SSR middleware helpers for Express, Fastify, Hono, and other Node.js HTTP frameworks.\n *\n * Provides two handler factories that wrap the SSR rendering pipeline and\n * emit a complete HTML document response. Both accept a static VNode **or**\n * a per-request factory function so route-specific data can be threaded into\n * the render tree.\n *\n * @example Express — static VNode\n * ```ts\n * import express from 'express';\n * import { createSSRHandler } from '@jasonshimmy/custom-elements-runtime/ssr-middleware';\n * import { html } from '@jasonshimmy/custom-elements-runtime';\n *\n * const app = express();\n * app.get('/', createSSRHandler(html`<my-app />`, {\n * render: { dsd: true, jit: { extendedColors: true } },\n * }));\n * ```\n *\n * @example Express — per-request factory\n * ```ts\n * app.get('*', createSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * { render: { dsd: true }, head: '<link rel=\"stylesheet\" href=\"/app.css\">' },\n * ));\n * ```\n *\n * @example Streaming variant\n * ```ts\n * app.get('*', createStreamingSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * ));\n * ```\n */\n\nimport { renderToStringWithJITCSS, renderToStream } from './ssr';\nimport type { VNode } from './runtime/types';\nimport type { RenderOptions } from './runtime/vdom-ssr';\nimport type { DSDRenderOptions } from './runtime/vdom-ssr-dsd';\nimport type { JITCSSOptions } from './runtime/style';\n\n// ---------------------------------------------------------------------------\n// Minimal framework-agnostic HTTP types\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal request interface compatible with Express, Fastify, Hono, and the\n * raw Node.js `IncomingMessage`. Extend or replace with your framework's\n * request type via the generic parameter on `createSSRHandler`.\n */\nexport interface MinimalRequest {\n url?: string;\n method?: string;\n headers?: Record<string, string | string[] | undefined>;\n}\n\n/**\n * Minimal response interface compatible with Express, Fastify, Hono, and the\n * raw Node.js `ServerResponse`. `write` is optional — handlers fall back to\n * buffering when it is absent.\n */\nexport interface MinimalResponse {\n setHeader(name: string, value: string): void;\n write?(chunk: string): boolean | void;\n end(data?: string): void;\n}\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/**\n * Options for {@link createSSRHandler} and {@link createStreamingSSRHandler}.\n */\nexport interface SSRMiddlewareOptions {\n /**\n * Render options forwarded to `renderToStringWithJITCSS`.\n * Defaults to `{ dsd: true }` so DSD output is on by default.\n */\n render?: RenderOptions & DSDRenderOptions & { jit?: JITCSSOptions };\n /**\n * Additional HTML inserted at the end of the `<head>` tag.\n * Use this to inject `<link>`, `<script>`, `<meta>`, or `<title>` tags.\n */\n head?: string;\n /**\n * When `true` (default), the response is wrapped in a complete\n * `<!DOCTYPE html>` document shell. Set to `false` if you want to\n * assemble the document yourself and only need the rendered fragment.\n */\n document?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction wrapInDocument(\n htmlWithStyles: string,\n head: string | undefined,\n wrapDocument: boolean,\n): string {\n if (!wrapDocument) return htmlWithStyles;\n\n // If the rendered HTML already contains a root <html> tag, inject extra\n // head tags and prepend the DOCTYPE — do not double-wrap.\n if (\n htmlWithStyles.trimStart().toLowerCase().startsWith('<html') ||\n htmlWithStyles.includes('</html>')\n ) {\n const extra = head ?? '';\n const withDoctype = htmlWithStyles.startsWith('<!DOCTYPE')\n ? htmlWithStyles\n : `<!DOCTYPE html>${htmlWithStyles}`;\n if (extra) {\n return withDoctype.includes('</head>')\n ? withDoctype.replace('</head>', `${extra}</head>`)\n : withDoctype;\n }\n return withDoctype;\n }\n\n // Minimal shell\n const headContent = head ?? '';\n return `<!DOCTYPE html><html><head>${headContent}</head><body>${htmlWithStyles}</body></html>`;\n}\n\n// ---------------------------------------------------------------------------\n// Handler factories\n// ---------------------------------------------------------------------------\n\n/**\n * Create a request handler that SSR-renders a VNode tree and sends the full\n * HTML document as the response.\n *\n * Compatible with Express, Fastify, Hono, and any framework that uses an\n * `(req, res)` handler signature. The generic `Req` parameter lets you use\n * your framework's typed request object.\n *\n * @param vnodeOrFactory - A static {@link VNode} **or** a (possibly async)\n * factory function that receives the request and returns the VNode to render.\n * @param options - Render and document-shell options.\n *\n * @example\n * ```ts\n * app.get('*', createSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * { render: { dsd: true, jit: { extendedColors: true } } },\n * ));\n * ```\n */\nexport function createSSRHandler<Req extends MinimalRequest = MinimalRequest>(\n vnodeOrFactory: VNode | ((req: Req) => VNode | Promise<VNode>),\n options?: SSRMiddlewareOptions,\n): (req: Req, res: MinimalResponse) => Promise<void> {\n const renderOptions: RenderOptions &\n DSDRenderOptions & { jit?: JITCSSOptions } = {\n dsd: true,\n ...options?.render,\n };\n const { head, document: wrapDocument = true } = options ?? {};\n\n return async (req, res) => {\n try {\n const vnode =\n typeof vnodeOrFactory === 'function'\n ? await vnodeOrFactory(req)\n : vnodeOrFactory;\n\n const { htmlWithStyles } = renderToStringWithJITCSS(vnode, renderOptions);\n\n const body = wrapInDocument(htmlWithStyles, head, wrapDocument);\n\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n res.end(body);\n } catch (err) {\n // Ensure the response is always closed to prevent the request hanging.\n // Re-throw so the framework's error handler can set the proper status code.\n try {\n res.setHeader('Content-Type', 'text/plain; charset=utf-8');\n res.end('Internal Server Error');\n } catch {\n // ignore secondary errors during error response\n }\n throw err;\n }\n };\n}\n\n/**\n * Create a request handler that SSR-renders a VNode tree and streams the HTML\n * response using chunked transfer encoding.\n *\n * Each chunk produced by the underlying {@link renderToStream} call is written\n * to the response as it becomes available, minimising Time-to-First-Byte.\n * The document shell preamble (`<!DOCTYPE html>…<body>`) is sent in the first\n * write so the browser can begin parsing immediately.\n *\n * @param vnodeOrFactory - A static {@link VNode} **or** a (possibly async)\n * factory function that receives the request and returns the VNode to render.\n * @param options - Render and document-shell options.\n *\n * @example\n * ```ts\n * app.get('*', createStreamingSSRHandler(\n * (req) => html`<my-app url=\"${req.url}\" />`,\n * { render: { dsd: true } },\n * ));\n * ```\n */\nexport function createStreamingSSRHandler<\n Req extends MinimalRequest = MinimalRequest,\n>(\n vnodeOrFactory: VNode | ((req: Req) => VNode | Promise<VNode>),\n options?: SSRMiddlewareOptions,\n): (req: Req, res: MinimalResponse) => Promise<void> {\n const renderOptions: RenderOptions &\n DSDRenderOptions & { jit?: JITCSSOptions } = {\n dsd: true,\n ...options?.render,\n };\n const { head, document: wrapDocument = true } = options ?? {};\n\n return async (req, res) => {\n try {\n const vnode =\n typeof vnodeOrFactory === 'function'\n ? await vnodeOrFactory(req)\n : vnodeOrFactory;\n\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n\n const stream = renderToStream(vnode, renderOptions);\n const reader = stream.getReader();\n\n if (res.write) {\n // Streaming path: pipe chunks directly to the response as they arrive.\n res.setHeader('Transfer-Encoding', 'chunked');\n if (wrapDocument) {\n res.write(`<!DOCTYPE html><html><head>${head ?? ''}</head><body>`);\n }\n let done = false;\n while (!done) {\n const { value, done: d } = await reader.read();\n if (value) res.write(value);\n done = d;\n }\n if (wrapDocument) {\n res.end('</body></html>');\n } else {\n res.end();\n }\n } else {\n // Buffered fallback: framework does not expose write(); collect and send as one response.\n const chunks: string[] = [];\n let done = false;\n while (!done) {\n const { value, done: d } = await reader.read();\n if (value) chunks.push(value);\n done = d;\n }\n const content = chunks.join('');\n const body = wrapDocument\n ? `<!DOCTYPE html><html><head>${head ?? ''}</head><body>${content}</body></html>`\n : content;\n res.end(body);\n }\n } catch (err) {\n // Ensure the response is always closed to prevent the request hanging.\n // Re-throw so the framework's error handler can set the proper status code.\n try {\n res.setHeader('Content-Type', 'text/plain; charset=utf-8');\n res.end('Internal Server Error');\n } catch {\n // ignore secondary errors during error response\n }\n throw err;\n }\n };\n}\n"],"names":["wrapInDocument","htmlWithStyles","head","wrapDocument","extra","withDoctype","createSSRHandler","vnodeOrFactory","options","renderOptions","req","res","vnode","renderToStringWithJITCSS","body","err","createStreamingSSRHandler","reader","renderToStream","done","value","d","chunks","content"],"mappings":";AAkGA,SAASA,EACPC,GACAC,GACAC,GACQ;AACR,MAAI,CAACA,EAAc,QAAOF;AAI1B,MACEA,EAAe,YAAY,cAAc,WAAW,OAAO,KAC3DA,EAAe,SAAS,SAAS,GACjC;AACA,UAAMG,IAAQF,KAAQ,IAChBG,IAAcJ,EAAe,WAAW,WAAW,IACrDA,IACA,kBAAkBA,CAAc;AACpC,WAAIG,KACKC,EAAY,SAAS,SAAS,IACjCA,EAAY,QAAQ,WAAW,GAAGD,CAAK,SAAS,IAG/CC;AAAA,EACT;AAIA,SAAO,8BADaH,KAAQ,EACoB,gBAAgBD,CAAc;AAChF;AA0BO,SAASK,EACdC,GACAC,GACmD;AACnD,QAAMC,IACyC;AAAA,IAC7C,KAAK;AAAA,IACL,GAAGD,GAAS;AAAA,EAAA,GAER,EAAE,MAAAN,GAAM,UAAUC,IAAe,GAAA,IAASK,KAAW,CAAA;AAE3D,SAAO,OAAOE,GAAKC,MAAQ;AACzB,QAAI;AACF,YAAMC,IACJ,OAAOL,KAAmB,aACtB,MAAMA,EAAeG,CAAG,IACxBH,GAEA,EAAE,gBAAAN,EAAA,IAAmBY,EAAyBD,GAAOH,CAAa,GAElEK,IAAOd,EAAeC,GAAgBC,GAAMC,CAAY;AAE9D,MAAAQ,EAAI,UAAU,gBAAgB,0BAA0B,GACxDA,EAAI,IAAIG,CAAI;AAAA,IACd,SAASC,GAAK;AAGZ,UAAI;AACF,QAAAJ,EAAI,UAAU,gBAAgB,2BAA2B,GACzDA,EAAI,IAAI,uBAAuB;AAAA,MACjC,QAAQ;AAAA,MAER;AACA,YAAMI;AAAA,IACR;AAAA,EACF;AACF;AAuBO,SAASC,EAGdT,GACAC,GACmD;AACnD,QAAMC,IACyC;AAAA,IAC7C,KAAK;AAAA,IACL,GAAGD,GAAS;AAAA,EAAA,GAER,EAAE,MAAAN,GAAM,UAAUC,IAAe,GAAA,IAASK,KAAW,CAAA;AAE3D,SAAO,OAAOE,GAAKC,MAAQ;AACzB,QAAI;AACF,YAAMC,IACJ,OAAOL,KAAmB,aACtB,MAAMA,EAAeG,CAAG,IACxBH;AAEN,MAAAI,EAAI,UAAU,gBAAgB,0BAA0B;AAGxD,YAAMM,IADSC,EAAeN,GAAOH,CAAa,EAC5B,UAAA;AAEtB,UAAIE,EAAI,OAAO;AAEb,QAAAA,EAAI,UAAU,qBAAqB,SAAS,GACxCR,KACFQ,EAAI,MAAM,8BAA8BT,KAAQ,EAAE,eAAe;AAEnE,YAAIiB,IAAO;AACX,eAAO,CAACA,KAAM;AACZ,gBAAM,EAAE,OAAAC,GAAO,MAAMC,MAAM,MAAMJ,EAAO,KAAA;AACxC,UAAIG,KAAOT,EAAI,MAAMS,CAAK,GAC1BD,IAAOE;AAAA,QACT;AACA,QAAIlB,IACFQ,EAAI,IAAI,gBAAgB,IAExBA,EAAI,IAAA;AAAA,MAER,OAAO;AAEL,cAAMW,IAAmB,CAAA;AACzB,YAAIH,IAAO;AACX,eAAO,CAACA,KAAM;AACZ,gBAAM,EAAE,OAAAC,GAAO,MAAMC,MAAM,MAAMJ,EAAO,KAAA;AACxC,UAAIG,KAAOE,EAAO,KAAKF,CAAK,GAC5BD,IAAOE;AAAA,QACT;AACA,cAAME,IAAUD,EAAO,KAAK,EAAE,GACxBR,IAAOX,IACT,8BAA8BD,KAAQ,EAAE,gBAAgBqB,CAAO,mBAC/DA;AACJ,QAAAZ,EAAI,IAAIG,CAAI;AAAA,MACd;AAAA,IACF,SAASC,GAAK;AAGZ,UAAI;AACF,QAAAJ,EAAI,UAAU,gBAAgB,2BAA2B,GACzDA,EAAI,IAAI,uBAAuB;AAAA,MACjC,QAAQ;AAAA,MAER;AACA,YAAMI;AAAA,IACR;AAAA,EACF;AACF;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./hooks-
|
|
2
|
-
`));return
|
|
3
|
-
`),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./hooks-x8M4knLc.cjs"),m=require("./namespace-helpers-ckeEOxpR.cjs"),b=require("./style-D40DsIqJ.cjs"),C=require("./css-utils-RqkyBWft.cjs"),R=require("./logger-CSALKaYm.cjs"),j=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);function A(t,r,e){const n=e.injectSvgNamespace??!0,s=e.injectKnownNamespaces??n,i={...t};return n&&r==="svg"&&!("xmlns"in i)?i.xmlns=m.SVG_NS:s&&r in m.TAG_NAMESPACE_MAP&&!("xmlns"in i)&&(i.xmlns=m.TAG_NAMESPACE_MAP[r]),Object.entries(i).map(([a,u])=>` ${a}="${o.escapeHTML(String(u))}"`).join("")}function P(t){return Object.entries(t).map(([r,e])=>` ${r}="${o.escapeHTML(String(e))}"`).join("")}function f(t,r){if(typeof t=="string")return o.escapeHTML(t);if(t.tag==="#text")return typeof t.children=="string"?o.escapeHTML(t.children):"";if(t.tag==="#anchor")return(Array.isArray(t.children)?t.children.filter(a=>a!=null):[]).map(a=>f(a,r)).join("");if(t.tag==="#raw")return typeof t.children=="string"?t.children:"";const e=t.props?.attrs?{...t.props.attrs}:{},n=A(e,t.tag,r??{});if(j.has(t.tag))return`<${t.tag}${n}>`;const s=Array.isArray(t.children)?t.children.filter(i=>i!=null).map(i=>f(i,r)).join(""):typeof t.children=="string"?o.escapeHTML(t.children):t.children?f(t.children,r):"";return`<${t.tag}${n}>${s}</${t.tag}>`}const g="<script>(function(){if(HTMLTemplateElement.prototype.hasOwnProperty('shadowRootMode'))return;document.querySelectorAll('template[shadowrootmode]').forEach(function(t){var m=t.getAttribute('shadowrootmode');var s=t.parentElement.attachShadow({mode:m});s.appendChild(t.content);t.remove();});})()<\/script>";function _(t){return t.includes("-")&&m.registry.has(t)}function D(t,r){const e=[C.baseReset];t.trim()&&e.push(t);const n=b.jitCSS(r);n.trim()&&e.push(n);const s=C.minifyCSS(e.join(`
|
|
2
|
+
`));return s?`<style>${s}</style>`:""}let p=null,E=0;function H(t){p=t,E=0}function I(){p=null}function y(t,r){if(!r.dsd)return f(t,r);if(typeof t=="string")return o.escapeHTML(t);const e=t.tag;if(e==="#text"||e==="#anchor"||e==="#raw")return f(t,r);if(_(e))return N(t,r);const n=t.props?.attrs?{...t.props.attrs}:{},s=A(n,e,r);if(j.has(e))return`<${e}${s}>`;const i=T(t.children,r);return`<${e}${s}>${i}</${e}>`}function N(t,r){const e=t.tag,n=m.registry.get(e),s=t.props?.attrs??{},i=P(s);if(!n){const h=T(t.children,r);return`<${e}${i}><template shadowrootmode="open"></template>${h}</${e}>`}const a=n.hydrate,u=a&&a!=="load"?` data-cer-hydrate="${a}"`:"",{shadowVNode:l,useStyleCSS:d,asyncPromise:S}=o.runComponentSSRRender(n,s,e);if(S&&p===null&&R.devWarn(`[SSR] Component "${e}" has an async render function. In standard SSR the shadow DOM will be empty. Use renderToStream() for incremental async component streaming.`),S&&p!==null){const h=`cer-stream-${E++}`,w=T(t.children,r);return p.push({id:h,tag:e,attrsString:i,hydrateAttr:u,useStyleCSS:d,lightDOM:w,opts:r,promise:S}),`<${e} id="${h}"${i}${u}><template shadowrootmode="open"></template>${w}</${e}>`}let c="";l!=null&&(Array.isArray(l)?c=l.map(h=>y(h,r)).join(""):c=y(l,r));const $=D(d,c),O=T(t.children,r);return`<${e}${i}${u}><template shadowrootmode="open">${$}${c}</template>${O}</${e}>`}function T(t,r){return t?typeof t=="string"?o.escapeHTML(t):Array.isArray(t)?t.filter(e=>e!=null).map(e=>y(e,r)).join(""):y(t,r):""}function L(t,r){const e={dsd:!0,...r},n=y(t,e);return e.dsdPolyfill!==!1?n.includes("</body>")?n.replace("</body>",`${g}</body>`):n+g:n}function M(t,r){const{jit:e,dsd:n,dsdPolyfill:s,...i}=r??{};e&&b.enableJITCSS(e),o.beginSSRGlobalStyleCollection();let a,u;try{n?a=L(t,{...i,dsd:!0,dsdPolyfill:!1}):a=f(t,i)}finally{u=o.endSSRGlobalStyleCollection()}const l=b.jitCSS(a),d=u.join(`
|
|
3
|
+
`),S=[];l&&S.push(`<style id="cer-ssr-jit">${l}</style>`),d.trim()&&S.push(`<style id="cer-ssr-global">${d}</style>`);let c=a;if(S.length){const $=S.join("");c=a.includes("</head>")?a.replace("</head>",`${$}</head>`):`${$}${a}`}return n&&s!==!1&&(c=c.includes("</body>")?c.replace("</body>",`${g}</body>`):c+g),{html:a,css:l,globalStyles:d,htmlWithStyles:c}}function q(t,r){return M(t,{...r,dsd:!0})}function k(t,r){return new ReadableStream({async start(e){const n=[];H(n);try{const{htmlWithStyles:s}=M(t,r);e.enqueue(s)}catch(s){e.error(s);return}finally{I()}for(const s of n)try{const i=await s.promise,a=Array.isArray(i)?i.map(d=>y(d,s.opts)).join(""):y(i,s.opts),l=`${D(s.useStyleCSS,a)}${a}`;e.enqueue(`<script>(function(){var e=document.getElementById(${JSON.stringify(s.id)});if(!e)return;var s=e.shadowRoot;if(!s&&e.attachShadow)try{s=e.attachShadow({mode:'open'});}catch(_){};if(s)s.innerHTML=${JSON.stringify(l)};e.removeAttribute('id');})();<\/script>`)}catch{}e.close()}})}exports.clearRegisteredEntityMap=o.clearRegisteredEntityMap;exports.loadEntityMap=o.loadEntityMap;exports.registerEntityMap=o.registerEntityMap;exports.DSD_POLYFILL_SCRIPT=g;exports.renderToStream=k;exports.renderToString=f;exports.renderToStringDSD=L;exports.renderToStringWithJITCSS=M;exports.renderToStringWithJITCSSDSD=q;
|
|
4
4
|
//# sourceMappingURL=custom-elements-runtime.ssr.cjs.js.map
|