@ecopages/lit 0.2.0-alpha.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/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@ecopages/lit` are documented here.
4
+
5
+ > **Note:** Changelog tracking begins at version `0.2.0`. Changes prior to this release are not recorded here but are available in the git history.
6
+
7
+ ## [UNRELEASED] — TBD
8
+
9
+ ### Features
10
+
11
+ - Aligned Lit renderer with full orchestration mode — removed legacy rendering path (`fc07bdb0`).
12
+ - Integration updated to work with the new lazy dependency map and global injector rendering mode.
13
+
14
+ ### Refactoring
15
+
16
+ - Ambient module declarations cleaned up (`5f46ecc5`).
17
+ - Updated test suite for esbuild adapter and Node.js runtime compatibility (`31a44458`).
18
+
19
+ ### Tests
20
+
21
+ - Updated integration tests to the new orchestration model.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-present Andrea Zanenghi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Ecopages Lit Integration Plugin
2
+
3
+ The `@ecopages/lit` package enables the integration of [Lit](https://lit.dev/), a powerful library for building fast, lightweight web components. This integration is optimized for use alongside `@ecopages/kitajs`, facilitating the use of Lit within a proper HTML template engine context provided by Kita. This combination allows developers to leverage the best of both worlds: the component-based architecture of Lit and the JSX template capabilities of Kita, enhancing the development of dynamic and interactive web pages.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ bunx jsr add @ecopages/lit
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ For effective utilization of Lit in your Ecopages projects, it is recommended to use it in conjunction with Kita. This ensures a seamless development experience, allowing you to incorporate Lit components within JSX templates effortlessly. Configure your project to include both `@ecopages/lit` and `@ecopages/kitajs` as follows:
14
+
15
+ ```ts
16
+ import { ConfigBuilder } from '@ecopages/core';
17
+ import { kitajsPlugin } from '@ecopages/kitajs';
18
+ import { litPlugin } from '@ecopages/lit';
19
+
20
+ const config = await new ConfigBuilder()
21
+ .setBaseUrl(import.meta.env.ECOPAGES_BASE_URL)
22
+ .setIntegrations([kitajsPlugin(), litPlugin()])
23
+ .build();
24
+
25
+ export default config;
26
+ ```
27
+
28
+ Adopting this setup empowers developers to fully exploit Lit's capabilities within the Ecopages framework, paving the way for the creation of rich, interactive web components.
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@ecopages/lit",
3
+ "version": "0.2.0-alpha.1",
4
+ "description": "Ecopages lit integration",
5
+ "keywords": [
6
+ "ecopages",
7
+ "lit",
8
+ "plugin"
9
+ ],
10
+ "license": "MIT",
11
+ "main": "./src/lit.plugin.js",
12
+ "types": "./src/lit.plugin.d.ts",
13
+ "type": "module",
14
+ "exports": {
15
+ ".": {
16
+ "default": "./src/lit.plugin.js",
17
+ "types": "./src/lit.plugin.d.ts"
18
+ },
19
+ "./styled-mixin": {
20
+ "default": "./src/styled-mixin.js",
21
+ "types": "./src/styled-mixin.d.ts"
22
+ },
23
+ "./styled-mixin.ts": {
24
+ "default": "./src/styled-mixin.js",
25
+ "types": "./src/styled-mixin.d.ts"
26
+ }
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/ecopages/ecopages.git",
31
+ "directory": "packages/integrations/lit"
32
+ },
33
+ "peerDependencies": {
34
+ "@ecopages/core": "0.2.0-alpha.1",
35
+ "@lit-labs/ssr": "^3.3.0",
36
+ "@lit-labs/ssr-client": "^1.1.7",
37
+ "lit": "^3.2.1"
38
+ }
39
+ }
@@ -0,0 +1,5 @@
1
+ declare const originalConsoleWarn: {
2
+ (...data: any[]): void;
3
+ (...data: any[]): void;
4
+ (message?: any, ...optionalParams: any[]): void;
5
+ };
package/src/console.js ADDED
@@ -0,0 +1,9 @@
1
+ const originalConsoleWarn = console.warn;
2
+ console.warn = (...messages) => {
3
+ if (messages.some(
4
+ (message) => typeof message === "string" && message.includes("'CustomElementRegistry' already has")
5
+ )) {
6
+ return;
7
+ }
8
+ originalConsoleWarn.apply(console, messages);
9
+ };
package/src/console.ts ADDED
@@ -0,0 +1,19 @@
1
+ const originalConsoleWarn = console.warn;
2
+
3
+ /**
4
+ * Suppresses the warning about CustomElementRegistry already being defined in ssr-dom-shim by lit
5
+ * https://github.com/lit/lit/blob/bd881370b83d366f7654dd510731242a68949a20/packages/labs/ssr-dom-shim/src/index.ts#L140
6
+ * Complete Error Log:
7
+ * 'CustomElementRegistry' already has "lit-counter" defined. This may have been caused by live reload or hot module replacement in which case it can be safely ignored.
8
+ * Make sure to test your application with a production build as repeat registrations will throw in production.
9
+ */
10
+ console.warn = (...messages: any[]) => {
11
+ if (
12
+ messages.some(
13
+ (message) => typeof message === 'string' && message.includes("'CustomElementRegistry' already has"),
14
+ )
15
+ ) {
16
+ return;
17
+ }
18
+ originalConsoleWarn.apply(console, messages);
19
+ };
@@ -0,0 +1 @@
1
+ export declare const litElementHydrateScript = "var k=globalThis,y=k.trustedTypes,p=y?y.createPolicy(\"lit-html\",{createHTML:(q)=>q}):void 0;var P=`lit$${Math.random().toFixed(9).slice(2)}$`,v=\"?\"+P,Kq=`<${v}>`,x=document,C=()=>x.createComment(\"\"),S=(q)=>q===null||typeof q!=\"object\"&&typeof q!=\"function\",L=Array.isArray,h=(q)=>L(q)||typeof q?.[Symbol.iterator]==\"function\";var U=/<(?:(!--|\\/[^a-zA-Z])|(\\/?[a-zA-Z][^>\\s]*)|(\\/?$))/g,m=/-->/g,a=/>/g,$=/>|[ \\t\\n\\f\\r](?:([^\\s\"'>=\\/]+)([ \\t\\n\\f\\r]*=[ \\t\\n\\f\\r]*(?:[^ \\t\\n\\f\\r\"'\\`<>=]|(\"|')|))|$)/g,c=/'/g,l=/\"/g,r=/^(?:script|style|textarea|title)$/i,M=(q)=>(D,...F)=>({_$litType$:q,strings:D,values:F}),Aq=M(1),Pq=M(2),Vq=M(3),V=Symbol.for(\"lit-noChange\"),B=Symbol.for(\"lit-nothing\"),n=new WeakMap,w=x.createTreeWalker(x,129);function o(q,D){if(!L(q)||!q.hasOwnProperty(\"raw\"))throw Error(\"invalid template strings array\");return p!==void 0?p.createHTML(D):D}var e=(q,D)=>{let F=q.length-1,J=[],G,O=D===2?\"<svg>\":D===3?\"<math>\":\"\",K=U;for(let W=0;W<F;W++){let Q=q[W],Y,X,b=-1,A=0;while(A<Q.length&&(K.lastIndex=A,X=K.exec(Q),X!==null))A=K.lastIndex,K===U?X[1]===\"!--\"?K=m:X[1]!==void 0?K=a:X[2]!==void 0?(r.test(X[2])&&(G=RegExp(\"</\"+X[2],\"g\")),K=$):X[3]!==void 0&&(K=$):K===$?X[0]===\">\"?(K=G??U,b=-1):X[1]===void 0?b=-2:(b=K.lastIndex-X[2].length,Y=X[1],K=X[3]===void 0?$:X[3]==='\"'?l:c):K===l||K===c?K=$:K===m||K===a?K=U:(K=$,G=void 0);const _=K===$&&q[W+1].startsWith(\"/>\")?\" \":\"\";O+=K===U?Q+Kq:b>=0?(J.push(Y),Q.slice(0,b)+\"$lit$\"+Q.slice(b)+P+_):Q+P+(b===-2?W:_)}return[o(q,O+(q[F]||\"<?>\")+(D===2?\"</svg>\":D===3?\"</math>\":\"\")),J]};class g{constructor({strings:q,_$litType$:D},F){let J;this.parts=[];let G=0,O=0,K=q.length-1,W=this.parts,[Q,Y]=e(q,D);if(this.el=g.createElement(Q,F),w.currentNode=this.el.content,D===2||D===3){const X=this.el.content.firstChild;X.replaceWith(...X.childNodes)}while((J=w.nextNode())!==null&&W.length<K){if(J.nodeType===1){if(J.hasAttributes())for(const X of J.getAttributeNames())if(X.endsWith(\"$lit$\")){const b=Y[O++],A=J.getAttribute(X).split(P),_=/([.?@])?(.*)/.exec(b);W.push({type:1,index:G,name:_[2],strings:A,ctor:_[1]===\".\"?R:_[1]===\"?\"?E:_[1]===\"@\"?d:I}),J.removeAttribute(X)}else X.startsWith(P)&&(W.push({type:6,index:G}),J.removeAttribute(X));if(r.test(J.tagName)){const X=J.textContent.split(P),b=X.length-1;if(b>0){J.textContent=y?y.emptyScript:\"\";for(let A=0;A<b;A++)J.append(X[A],C()),w.nextNode(),W.push({type:2,index:++G});J.append(X[b],C())}}}else if(J.nodeType===8)if(J.data===v)W.push({type:2,index:G});else{let X=-1;while((X=J.data.indexOf(P,X+1))!==-1)W.push({type:7,index:G}),X+=P.length-1}G++}}static createElement(q,D){const F=x.createElement(\"template\");return F.innerHTML=q,F}}function z(q,D,F=q,J){if(D===V)return D;let G=J!==void 0?F._$Co?.[J]:F._$Cl,O=S(D)?void 0:D._$litDirective$;return G?.constructor!==O&&(G?._$AO?.(!1),O===void 0?G=void 0:(G=new O(q),G._$AT(q,F,J)),J!==void 0?(F._$Co??=[])[J]=G:F._$Cl=G),G!==void 0&&(D=z(q,G._$AS(q,D.values),G,J)),D}class j{constructor(q,D){this._$AV=[],this._$AN=void 0,this._$AD=q,this._$AM=D}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(q){const{el:{content:D},parts:F}=this._$AD,J=(q?.creationScope??x).importNode(D,!0);w.currentNode=J;let G=w.nextNode(),O=0,K=0,W=F[0];while(W!==void 0){if(O===W.index){let Q;W.type===2?Q=new H(G,G.nextSibling,this,q):W.type===1?Q=new W.ctor(G,W.name,W.strings,this,q):W.type===6&&(Q=new f(G,this,q)),this._$AV.push(Q),W=F[++K]}O!==W?.index&&(G=w.nextNode(),O++)}return w.currentNode=x,J}p(q){let D=0;for(const F of this._$AV)F!==void 0&&(F.strings!==void 0?(F._$AI(q,F,D),D+=F.strings.length-2):F._$AI(q[D])),D++}}class H{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(q,D,F,J){this.type=2,this._$AH=B,this._$AN=void 0,this._$AA=q,this._$AB=D,this._$AM=F,this.options=J,this._$Cv=J?.isConnected??!0}get parentNode(){let q=this._$AA.parentNode,D=this._$AM;return D!==void 0&&q?.nodeType===11&&(q=D.parentNode),q}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(q,D=this){q=z(this,q,D),S(q)?q===B||q==null||q===\"\"?(this._$AH!==B&&this._$AR(),this._$AH=B):q!==this._$AH&&q!==V&&this._(q):q._$litType$!==void 0?this.$(q):q.nodeType!==void 0?this.T(q):h(q)?this.k(q):this._(q)}O(q){return this._$AA.parentNode.insertBefore(q,this._$AB)}T(q){this._$AH!==q&&(this._$AR(),this._$AH=this.O(q))}_(q){this._$AH!==B&&S(this._$AH)?this._$AA.nextSibling.data=q:this.T(x.createTextNode(q)),this._$AH=q}$(q){const{values:D,_$litType$:F}=q,J=typeof F==\"number\"?this._$AC(q):(F.el===void 0&&(F.el=g.createElement(o(F.h,F.h[0]),this.options)),F);if(this._$AH?._$AD===J)this._$AH.p(D);else{const G=new j(J,this),O=G.u(this.options);G.p(D),this.T(O),this._$AH=G}}_$AC(q){let D=n.get(q.strings);return D===void 0&&n.set(q.strings,D=new g(q)),D}k(q){L(this._$AH)||(this._$AH=[],this._$AR());let D=this._$AH,F,J=0;for(const G of q)J===D.length?D.push(F=new H(this.O(C()),this.O(C()),this,this.options)):F=D[J],F._$AI(G),J++;J<D.length&&(this._$AR(F&&F._$AB.nextSibling,J),D.length=J)}_$AR(q=this._$AA.nextSibling,D){for(this._$AP?.(!1,!0,D);q&&q!==this._$AB;){const F=q.nextSibling;q.remove(),q=F}}setConnected(q){this._$AM===void 0&&(this._$Cv=q,this._$AP?.(q))}}class I{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(q,D,F,J,G){this.type=1,this._$AH=B,this._$AN=void 0,this.element=q,this.name=D,this._$AM=J,this.options=G,F.length>2||F[0]!==\"\"||F[1]!==\"\"?(this._$AH=Array(F.length-1).fill(new String),this.strings=F):this._$AH=B}_$AI(q,D=this,F,J){let G=this.strings,O=!1;if(G===void 0)q=z(this,q,D,0),O=!S(q)||q!==this._$AH&&q!==V,O&&(this._$AH=q);else{let K=q,W,Q;for(q=G[0],W=0;W<G.length-1;W++)Q=z(this,K[F+W],D,W),Q===V&&(Q=this._$AH[W]),O||=!S(Q)||Q!==this._$AH[W],Q===B?q=B:q!==B&&(q+=(Q??\"\")+G[W+1]),this._$AH[W]=Q}O&&!J&&this.j(q)}j(q){q===B?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,q??\"\")}}class R extends I{constructor(){super(...arguments),this.type=3}j(q){this.element[this.name]=q===B?void 0:q}}class E extends I{constructor(){super(...arguments),this.type=4}j(q){this.element.toggleAttribute(this.name,!!q&&q!==B)}}class d extends I{constructor(q,D,F,J,G){super(q,D,F,J,G),this.type=5}_$AI(q,D=this){if((q=z(this,q,D,0)??B)===V)return;const F=this._$AH,J=q===B&&F!==B||q.capture!==F.capture||q.once!==F.once||q.passive!==F.passive,G=q!==B&&(F===B||J);J&&this.element.removeEventListener(this.name,this,F),G&&this.element.addEventListener(this.name,this,q),this._$AH=q}handleEvent(q){typeof this._$AH==\"function\"?this._$AH.call(this.options?.host??this.element,q):this._$AH.handleEvent(q)}}class f{constructor(q,D,F){this.element=q,this.type=6,this._$AN=void 0,this._$AM=D,this.options=F}get _$AU(){return this._$AM._$AU}_$AI(q){z(this,q)}}var Z={M:\"$lit$\",P,A:v,C:1,L:e,R:j,D:h,V:z,I:H,H:I,N:E,U:d,B:R,F:f},Oq=k.litHtmlPolyfillSupport;Oq?.(g,H),(k.litHtmlVersions??=[]).push(\"3.2.1\");var i=(q,D,F)=>{let J=F?.renderBefore??D,G=J._$litPart$;if(G===void 0){const O=F?.renderBefore??null;J._$litPart$=G=new H(D.insertBefore(C(),O),O,void 0,F??{})}return G._$AI(q),G};var u=null,s={boundAttributeSuffix:Z.M,marker:Z.P,markerMatch:Z.A,HTML_RESULT:Z.C,getTemplateHtml:Z.L,overrideDirectiveResolve:(q,D)=>class extends q{_$AS(F,J){return D(this,J)}},patchDirectiveResolve:(q,D)=>{if(q.prototype._$AS!==D){u??=q.prototype._$AS.name;for(let F=q.prototype;F!==Object.prototype;F=Object.getPrototypeOf(F))if(F.hasOwnProperty(u))return void(F[u]=D);throw Error(\"Internal error: It is possible that both dev mode and production mode Lit was mixed together during SSR. Please comment on the issue: https://github.com/lit/lit/issues/4527\")}},setDirectiveClass(q,D){q._$litDirective$=D},getAttributePartCommittedValue:(q,D,F)=>{let J=V;return q.j=(G)=>J=G,q._$AI(D,q,F),J},connectedDisconnectable:(q)=>({...q,_$AU:!0}),resolveDirective:Z.V,AttributePart:Z.H,PropertyPart:Z.B,BooleanAttributePart:Z.N,EventPart:Z.U,ElementPart:Z.F,TemplateInstance:Z.R,isIterable:Z.D,ChildPart:Z.I};var T={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6};var t=(q)=>q===null||typeof q!=\"object\"&&typeof q!=\"function\";var qq=(q,D)=>D===void 0?q?._$litType$!==void 0:q?._$litType$===D,Dq=(q)=>q?._$litType$?.h!=null;var Fq=(q)=>q.strings===void 0;var{TemplateInstance:Qq,isIterable:Wq,resolveDirective:Gq,ChildPart:N,ElementPart:Xq}=s,Jq=(q,D,F={})=>{if(D._$litPart$!==void 0)throw Error(\"container already contains a live render\");let J,G,O,K=[],W=document.createTreeWalker(D,NodeFilter.SHOW_COMMENT),Q;while((Q=W.nextNode())!==null){const Y=Q.data;if(Y.startsWith(\"lit-part\")){if(K.length===0&&J!==void 0)throw Error(`There must be only one root part per container. Found a part marker (${Q}) when we already have a root part marker (${G})`);O=Yq(q,Q,K,F),J===void 0&&(J=O),G??=Q}else if(Y.startsWith(\"lit-node\"))Zq(Q,K,F);else if(Y.startsWith(\"/lit-part\")){if(K.length===1&&O!==J)throw Error(\"internal error\");O=Bq(Q,O,K)}}if(J===void 0){const Y=D instanceof ShadowRoot?\"{container.host.localName}'s shadow root\":D instanceof DocumentFragment?\"DocumentFragment\":D.localName;console.error(`There should be exactly one root part in a render container, but we didn't find any in ${Y}.`)}D._$litPart$=J},Yq=(q,D,F,J)=>{let G,O;if(F.length===0)O=new N(D,null,void 0,J),G=q;else{const K=F[F.length-1];if(K.type===\"template-instance\")O=new N(D,null,K.instance,J),K.instance._$AV.push(O),G=K.result.values[K.instancePartIndex++],K.templatePartIndex++;else if(K.type===\"iterable\"){O=new N(D,null,K.part,J);const W=K.iterator.next();if(W.done)throw G=void 0,K.done=!0,Error(\"Unhandled shorter than expected iterable\");G=W.value,K.part._$AH.push(O)}else O=new N(D,null,K.part,J)}if(G=Gq(O,G),G===V)F.push({part:O,type:\"leaf\"});else if(t(G))F.push({part:O,type:\"leaf\"}),O._$AH=G;else if(qq(G)){if(Dq(G))throw Error(\"compiled templates are not supported\");const K=\"lit-part \"+bq(G);if(D.data!==K)throw Error(\"Hydration value mismatch: Unexpected TemplateResult rendered to part\");{const W=N.prototype._$AC(G),Q=new Qq(W,O);F.push({type:\"template-instance\",instance:Q,part:O,templatePartIndex:0,instancePartIndex:0,result:G}),O._$AH=Q}}else Wq(G)?(F.push({part:O,type:\"iterable\",value:G,iterator:G[Symbol.iterator](),done:!1}),O._$AH=[]):(F.push({part:O,type:\"leaf\"}),O._$AH=G??\"\");return O},Bq=(q,D,F)=>{if(D===void 0)throw Error(\"unbalanced part marker\");D._$AB=q;const J=F.pop();if(J.type===\"iterable\"&&!J.iterator.next().done)throw Error(\"unexpected longer than expected iterable\");if(F.length>0)return F[F.length-1].part},Zq=(q,D,F)=>{const J=/lit-node (\\d+)/.exec(q.data),G=Number.parseInt(J[1]),O=q.nextElementSibling;if(O===null)throw Error(\"could not find node for attribute parts\");O.removeAttribute(\"defer-hydration\");const K=D[D.length-1];if(K.type!==\"template-instance\")throw Error(\"Hydration value mismatch: Primitive found where TemplateResult expected. This usually occurs due to conditional rendering that resulted in a different value or template being rendered between the server and client.\");{const W=K.instance;for(;;){const Q=W._$AD.parts[K.templatePartIndex];if(Q===void 0||Q.type!==T.ATTRIBUTE&&Q.type!==T.ELEMENT||Q.index!==G)break;if(Q.type===T.ATTRIBUTE){const Y=new Q.ctor(O,Q.name,Q.strings,K.instance,F),X=Fq(Y)?K.result.values[K.instancePartIndex]:K.result.values,b=!(Y.type===T.EVENT||Y.type===T.PROPERTY);Y._$AI(X,Y,K.instancePartIndex,b),K.instancePartIndex+=Q.strings.length-1,W._$AV.push(Y)}else{const Y=new Xq(O,K.instance,F);Gq(Y,K.result.values[K.instancePartIndex++]),W._$AV.push(Y)}K.templatePartIndex++}}},bq=(q)=>{const D=new Uint32Array(2).fill(5381);for(const J of q.strings)for(let G=0;G<J.length;G++)D[G%2]=33*D[G%2]^J.charCodeAt(G);const F=String.fromCharCode(...new Uint8Array(D.buffer));return btoa(F)};globalThis.litElementHydrateSupport=({LitElement:q})=>{const D=Object.getOwnPropertyDescriptor(Object.getPrototypeOf(q),\"observedAttributes\").get;Object.defineProperty(q,\"observedAttributes\",{get(){return[...D.call(this),\"defer-hydration\"]}});const F=q.prototype.attributeChangedCallback;q.prototype.attributeChangedCallback=function(K,W,Q){K===\"defer-hydration\"&&Q===null&&J.call(this),F.call(this,K,W,Q)};const J=q.prototype.connectedCallback;q.prototype.connectedCallback=function(){this.hasAttribute(\"defer-hydration\")||J.call(this)};const G=q.prototype.createRenderRoot;q.prototype.createRenderRoot=function(){return this.shadowRoot?(this._$AG=!0,this.shadowRoot):G.call(this)};const O=Object.getPrototypeOf(q.prototype).update;q.prototype.update=function(K){const W=this.render();if(O.call(this,K),this._$AG){this._$AG=!1;for(let Q=0;Q<this.attributes.length;Q++){const Y=this.attributes[Q];if(Y.name.startsWith(\"hydrate-internals-\")){const X=Y.name.slice(18);this.removeAttribute(X),this.removeAttribute(Y.name)}}Jq(W,this.renderRoot,this.renderOptions)}else i(W,this.renderRoot,this.renderOptions)}};";
@@ -0,0 +1,4 @@
1
+ const litElementHydrateScript = 'var k=globalThis,y=k.trustedTypes,p=y?y.createPolicy("lit-html",{createHTML:(q)=>q}):void 0;var P=`lit$${Math.random().toFixed(9).slice(2)}$`,v="?"+P,Kq=`<${v}>`,x=document,C=()=>x.createComment(""),S=(q)=>q===null||typeof q!="object"&&typeof q!="function",L=Array.isArray,h=(q)=>L(q)||typeof q?.[Symbol.iterator]=="function";var U=/<(?:(!--|\\/[^a-zA-Z])|(\\/?[a-zA-Z][^>\\s]*)|(\\/?$))/g,m=/-->/g,a=/>/g,$=/>|[ \\t\\n\\f\\r](?:([^\\s"\'>=\\/]+)([ \\t\\n\\f\\r]*=[ \\t\\n\\f\\r]*(?:[^ \\t\\n\\f\\r"\'\\`<>=]|("|\')|))|$)/g,c=/\'/g,l=/"/g,r=/^(?:script|style|textarea|title)$/i,M=(q)=>(D,...F)=>({_$litType$:q,strings:D,values:F}),Aq=M(1),Pq=M(2),Vq=M(3),V=Symbol.for("lit-noChange"),B=Symbol.for("lit-nothing"),n=new WeakMap,w=x.createTreeWalker(x,129);function o(q,D){if(!L(q)||!q.hasOwnProperty("raw"))throw Error("invalid template strings array");return p!==void 0?p.createHTML(D):D}var e=(q,D)=>{let F=q.length-1,J=[],G,O=D===2?"<svg>":D===3?"<math>":"",K=U;for(let W=0;W<F;W++){let Q=q[W],Y,X,b=-1,A=0;while(A<Q.length&&(K.lastIndex=A,X=K.exec(Q),X!==null))A=K.lastIndex,K===U?X[1]==="!--"?K=m:X[1]!==void 0?K=a:X[2]!==void 0?(r.test(X[2])&&(G=RegExp("</"+X[2],"g")),K=$):X[3]!==void 0&&(K=$):K===$?X[0]===">"?(K=G??U,b=-1):X[1]===void 0?b=-2:(b=K.lastIndex-X[2].length,Y=X[1],K=X[3]===void 0?$:X[3]===\'"\'?l:c):K===l||K===c?K=$:K===m||K===a?K=U:(K=$,G=void 0);const _=K===$&&q[W+1].startsWith("/>")?" ":"";O+=K===U?Q+Kq:b>=0?(J.push(Y),Q.slice(0,b)+"$lit$"+Q.slice(b)+P+_):Q+P+(b===-2?W:_)}return[o(q,O+(q[F]||"<?>")+(D===2?"</svg>":D===3?"</math>":"")),J]};class g{constructor({strings:q,_$litType$:D},F){let J;this.parts=[];let G=0,O=0,K=q.length-1,W=this.parts,[Q,Y]=e(q,D);if(this.el=g.createElement(Q,F),w.currentNode=this.el.content,D===2||D===3){const X=this.el.content.firstChild;X.replaceWith(...X.childNodes)}while((J=w.nextNode())!==null&&W.length<K){if(J.nodeType===1){if(J.hasAttributes())for(const X of J.getAttributeNames())if(X.endsWith("$lit$")){const b=Y[O++],A=J.getAttribute(X).split(P),_=/([.?@])?(.*)/.exec(b);W.push({type:1,index:G,name:_[2],strings:A,ctor:_[1]==="."?R:_[1]==="?"?E:_[1]==="@"?d:I}),J.removeAttribute(X)}else X.startsWith(P)&&(W.push({type:6,index:G}),J.removeAttribute(X));if(r.test(J.tagName)){const X=J.textContent.split(P),b=X.length-1;if(b>0){J.textContent=y?y.emptyScript:"";for(let A=0;A<b;A++)J.append(X[A],C()),w.nextNode(),W.push({type:2,index:++G});J.append(X[b],C())}}}else if(J.nodeType===8)if(J.data===v)W.push({type:2,index:G});else{let X=-1;while((X=J.data.indexOf(P,X+1))!==-1)W.push({type:7,index:G}),X+=P.length-1}G++}}static createElement(q,D){const F=x.createElement("template");return F.innerHTML=q,F}}function z(q,D,F=q,J){if(D===V)return D;let G=J!==void 0?F._$Co?.[J]:F._$Cl,O=S(D)?void 0:D._$litDirective$;return G?.constructor!==O&&(G?._$AO?.(!1),O===void 0?G=void 0:(G=new O(q),G._$AT(q,F,J)),J!==void 0?(F._$Co??=[])[J]=G:F._$Cl=G),G!==void 0&&(D=z(q,G._$AS(q,D.values),G,J)),D}class j{constructor(q,D){this._$AV=[],this._$AN=void 0,this._$AD=q,this._$AM=D}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(q){const{el:{content:D},parts:F}=this._$AD,J=(q?.creationScope??x).importNode(D,!0);w.currentNode=J;let G=w.nextNode(),O=0,K=0,W=F[0];while(W!==void 0){if(O===W.index){let Q;W.type===2?Q=new H(G,G.nextSibling,this,q):W.type===1?Q=new W.ctor(G,W.name,W.strings,this,q):W.type===6&&(Q=new f(G,this,q)),this._$AV.push(Q),W=F[++K]}O!==W?.index&&(G=w.nextNode(),O++)}return w.currentNode=x,J}p(q){let D=0;for(const F of this._$AV)F!==void 0&&(F.strings!==void 0?(F._$AI(q,F,D),D+=F.strings.length-2):F._$AI(q[D])),D++}}class H{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(q,D,F,J){this.type=2,this._$AH=B,this._$AN=void 0,this._$AA=q,this._$AB=D,this._$AM=F,this.options=J,this._$Cv=J?.isConnected??!0}get parentNode(){let q=this._$AA.parentNode,D=this._$AM;return D!==void 0&&q?.nodeType===11&&(q=D.parentNode),q}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(q,D=this){q=z(this,q,D),S(q)?q===B||q==null||q===""?(this._$AH!==B&&this._$AR(),this._$AH=B):q!==this._$AH&&q!==V&&this._(q):q._$litType$!==void 0?this.$(q):q.nodeType!==void 0?this.T(q):h(q)?this.k(q):this._(q)}O(q){return this._$AA.parentNode.insertBefore(q,this._$AB)}T(q){this._$AH!==q&&(this._$AR(),this._$AH=this.O(q))}_(q){this._$AH!==B&&S(this._$AH)?this._$AA.nextSibling.data=q:this.T(x.createTextNode(q)),this._$AH=q}$(q){const{values:D,_$litType$:F}=q,J=typeof F=="number"?this._$AC(q):(F.el===void 0&&(F.el=g.createElement(o(F.h,F.h[0]),this.options)),F);if(this._$AH?._$AD===J)this._$AH.p(D);else{const G=new j(J,this),O=G.u(this.options);G.p(D),this.T(O),this._$AH=G}}_$AC(q){let D=n.get(q.strings);return D===void 0&&n.set(q.strings,D=new g(q)),D}k(q){L(this._$AH)||(this._$AH=[],this._$AR());let D=this._$AH,F,J=0;for(const G of q)J===D.length?D.push(F=new H(this.O(C()),this.O(C()),this,this.options)):F=D[J],F._$AI(G),J++;J<D.length&&(this._$AR(F&&F._$AB.nextSibling,J),D.length=J)}_$AR(q=this._$AA.nextSibling,D){for(this._$AP?.(!1,!0,D);q&&q!==this._$AB;){const F=q.nextSibling;q.remove(),q=F}}setConnected(q){this._$AM===void 0&&(this._$Cv=q,this._$AP?.(q))}}class I{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(q,D,F,J,G){this.type=1,this._$AH=B,this._$AN=void 0,this.element=q,this.name=D,this._$AM=J,this.options=G,F.length>2||F[0]!==""||F[1]!==""?(this._$AH=Array(F.length-1).fill(new String),this.strings=F):this._$AH=B}_$AI(q,D=this,F,J){let G=this.strings,O=!1;if(G===void 0)q=z(this,q,D,0),O=!S(q)||q!==this._$AH&&q!==V,O&&(this._$AH=q);else{let K=q,W,Q;for(q=G[0],W=0;W<G.length-1;W++)Q=z(this,K[F+W],D,W),Q===V&&(Q=this._$AH[W]),O||=!S(Q)||Q!==this._$AH[W],Q===B?q=B:q!==B&&(q+=(Q??"")+G[W+1]),this._$AH[W]=Q}O&&!J&&this.j(q)}j(q){q===B?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,q??"")}}class R extends I{constructor(){super(...arguments),this.type=3}j(q){this.element[this.name]=q===B?void 0:q}}class E extends I{constructor(){super(...arguments),this.type=4}j(q){this.element.toggleAttribute(this.name,!!q&&q!==B)}}class d extends I{constructor(q,D,F,J,G){super(q,D,F,J,G),this.type=5}_$AI(q,D=this){if((q=z(this,q,D,0)??B)===V)return;const F=this._$AH,J=q===B&&F!==B||q.capture!==F.capture||q.once!==F.once||q.passive!==F.passive,G=q!==B&&(F===B||J);J&&this.element.removeEventListener(this.name,this,F),G&&this.element.addEventListener(this.name,this,q),this._$AH=q}handleEvent(q){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,q):this._$AH.handleEvent(q)}}class f{constructor(q,D,F){this.element=q,this.type=6,this._$AN=void 0,this._$AM=D,this.options=F}get _$AU(){return this._$AM._$AU}_$AI(q){z(this,q)}}var Z={M:"$lit$",P,A:v,C:1,L:e,R:j,D:h,V:z,I:H,H:I,N:E,U:d,B:R,F:f},Oq=k.litHtmlPolyfillSupport;Oq?.(g,H),(k.litHtmlVersions??=[]).push("3.2.1");var i=(q,D,F)=>{let J=F?.renderBefore??D,G=J._$litPart$;if(G===void 0){const O=F?.renderBefore??null;J._$litPart$=G=new H(D.insertBefore(C(),O),O,void 0,F??{})}return G._$AI(q),G};var u=null,s={boundAttributeSuffix:Z.M,marker:Z.P,markerMatch:Z.A,HTML_RESULT:Z.C,getTemplateHtml:Z.L,overrideDirectiveResolve:(q,D)=>class extends q{_$AS(F,J){return D(this,J)}},patchDirectiveResolve:(q,D)=>{if(q.prototype._$AS!==D){u??=q.prototype._$AS.name;for(let F=q.prototype;F!==Object.prototype;F=Object.getPrototypeOf(F))if(F.hasOwnProperty(u))return void(F[u]=D);throw Error("Internal error: It is possible that both dev mode and production mode Lit was mixed together during SSR. Please comment on the issue: https://github.com/lit/lit/issues/4527")}},setDirectiveClass(q,D){q._$litDirective$=D},getAttributePartCommittedValue:(q,D,F)=>{let J=V;return q.j=(G)=>J=G,q._$AI(D,q,F),J},connectedDisconnectable:(q)=>({...q,_$AU:!0}),resolveDirective:Z.V,AttributePart:Z.H,PropertyPart:Z.B,BooleanAttributePart:Z.N,EventPart:Z.U,ElementPart:Z.F,TemplateInstance:Z.R,isIterable:Z.D,ChildPart:Z.I};var T={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6};var t=(q)=>q===null||typeof q!="object"&&typeof q!="function";var qq=(q,D)=>D===void 0?q?._$litType$!==void 0:q?._$litType$===D,Dq=(q)=>q?._$litType$?.h!=null;var Fq=(q)=>q.strings===void 0;var{TemplateInstance:Qq,isIterable:Wq,resolveDirective:Gq,ChildPart:N,ElementPart:Xq}=s,Jq=(q,D,F={})=>{if(D._$litPart$!==void 0)throw Error("container already contains a live render");let J,G,O,K=[],W=document.createTreeWalker(D,NodeFilter.SHOW_COMMENT),Q;while((Q=W.nextNode())!==null){const Y=Q.data;if(Y.startsWith("lit-part")){if(K.length===0&&J!==void 0)throw Error(`There must be only one root part per container. Found a part marker (${Q}) when we already have a root part marker (${G})`);O=Yq(q,Q,K,F),J===void 0&&(J=O),G??=Q}else if(Y.startsWith("lit-node"))Zq(Q,K,F);else if(Y.startsWith("/lit-part")){if(K.length===1&&O!==J)throw Error("internal error");O=Bq(Q,O,K)}}if(J===void 0){const Y=D instanceof ShadowRoot?"{container.host.localName}\'s shadow root":D instanceof DocumentFragment?"DocumentFragment":D.localName;console.error(`There should be exactly one root part in a render container, but we didn\'t find any in ${Y}.`)}D._$litPart$=J},Yq=(q,D,F,J)=>{let G,O;if(F.length===0)O=new N(D,null,void 0,J),G=q;else{const K=F[F.length-1];if(K.type==="template-instance")O=new N(D,null,K.instance,J),K.instance._$AV.push(O),G=K.result.values[K.instancePartIndex++],K.templatePartIndex++;else if(K.type==="iterable"){O=new N(D,null,K.part,J);const W=K.iterator.next();if(W.done)throw G=void 0,K.done=!0,Error("Unhandled shorter than expected iterable");G=W.value,K.part._$AH.push(O)}else O=new N(D,null,K.part,J)}if(G=Gq(O,G),G===V)F.push({part:O,type:"leaf"});else if(t(G))F.push({part:O,type:"leaf"}),O._$AH=G;else if(qq(G)){if(Dq(G))throw Error("compiled templates are not supported");const K="lit-part "+bq(G);if(D.data!==K)throw Error("Hydration value mismatch: Unexpected TemplateResult rendered to part");{const W=N.prototype._$AC(G),Q=new Qq(W,O);F.push({type:"template-instance",instance:Q,part:O,templatePartIndex:0,instancePartIndex:0,result:G}),O._$AH=Q}}else Wq(G)?(F.push({part:O,type:"iterable",value:G,iterator:G[Symbol.iterator](),done:!1}),O._$AH=[]):(F.push({part:O,type:"leaf"}),O._$AH=G??"");return O},Bq=(q,D,F)=>{if(D===void 0)throw Error("unbalanced part marker");D._$AB=q;const J=F.pop();if(J.type==="iterable"&&!J.iterator.next().done)throw Error("unexpected longer than expected iterable");if(F.length>0)return F[F.length-1].part},Zq=(q,D,F)=>{const J=/lit-node (\\d+)/.exec(q.data),G=Number.parseInt(J[1]),O=q.nextElementSibling;if(O===null)throw Error("could not find node for attribute parts");O.removeAttribute("defer-hydration");const K=D[D.length-1];if(K.type!=="template-instance")throw Error("Hydration value mismatch: Primitive found where TemplateResult expected. This usually occurs due to conditional rendering that resulted in a different value or template being rendered between the server and client.");{const W=K.instance;for(;;){const Q=W._$AD.parts[K.templatePartIndex];if(Q===void 0||Q.type!==T.ATTRIBUTE&&Q.type!==T.ELEMENT||Q.index!==G)break;if(Q.type===T.ATTRIBUTE){const Y=new Q.ctor(O,Q.name,Q.strings,K.instance,F),X=Fq(Y)?K.result.values[K.instancePartIndex]:K.result.values,b=!(Y.type===T.EVENT||Y.type===T.PROPERTY);Y._$AI(X,Y,K.instancePartIndex,b),K.instancePartIndex+=Q.strings.length-1,W._$AV.push(Y)}else{const Y=new Xq(O,K.instance,F);Gq(Y,K.result.values[K.instancePartIndex++]),W._$AV.push(Y)}K.templatePartIndex++}}},bq=(q)=>{const D=new Uint32Array(2).fill(5381);for(const J of q.strings)for(let G=0;G<J.length;G++)D[G%2]=33*D[G%2]^J.charCodeAt(G);const F=String.fromCharCode(...new Uint8Array(D.buffer));return btoa(F)};globalThis.litElementHydrateSupport=({LitElement:q})=>{const D=Object.getOwnPropertyDescriptor(Object.getPrototypeOf(q),"observedAttributes").get;Object.defineProperty(q,"observedAttributes",{get(){return[...D.call(this),"defer-hydration"]}});const F=q.prototype.attributeChangedCallback;q.prototype.attributeChangedCallback=function(K,W,Q){K==="defer-hydration"&&Q===null&&J.call(this),F.call(this,K,W,Q)};const J=q.prototype.connectedCallback;q.prototype.connectedCallback=function(){this.hasAttribute("defer-hydration")||J.call(this)};const G=q.prototype.createRenderRoot;q.prototype.createRenderRoot=function(){return this.shadowRoot?(this._$AG=!0,this.shadowRoot):G.call(this)};const O=Object.getPrototypeOf(q.prototype).update;q.prototype.update=function(K){const W=this.render();if(O.call(this,K),this._$AG){this._$AG=!1;for(let Q=0;Q<this.attributes.length;Q++){const Y=this.attributes[Q];if(Y.name.startsWith("hydrate-internals-")){const X=Y.name.slice(18);this.removeAttribute(X),this.removeAttribute(Y.name)}}Jq(W,this.renderRoot,this.renderOptions)}else i(W,this.renderRoot,this.renderOptions)}};';
2
+ export {
3
+ litElementHydrateScript
4
+ };
@@ -0,0 +1,2 @@
1
+ export const litElementHydrateScript =
2
+ 'var k=globalThis,y=k.trustedTypes,p=y?y.createPolicy("lit-html",{createHTML:(q)=>q}):void 0;var P=`lit$${Math.random().toFixed(9).slice(2)}$`,v="?"+P,Kq=`<${v}>`,x=document,C=()=>x.createComment(""),S=(q)=>q===null||typeof q!="object"&&typeof q!="function",L=Array.isArray,h=(q)=>L(q)||typeof q?.[Symbol.iterator]=="function";var U=/<(?:(!--|\\/[^a-zA-Z])|(\\/?[a-zA-Z][^>\\s]*)|(\\/?$))/g,m=/-->/g,a=/>/g,$=/>|[ \\t\\n\\f\\r](?:([^\\s"\'>=\\/]+)([ \\t\\n\\f\\r]*=[ \\t\\n\\f\\r]*(?:[^ \\t\\n\\f\\r"\'\\`<>=]|("|\')|))|$)/g,c=/\'/g,l=/"/g,r=/^(?:script|style|textarea|title)$/i,M=(q)=>(D,...F)=>({_$litType$:q,strings:D,values:F}),Aq=M(1),Pq=M(2),Vq=M(3),V=Symbol.for("lit-noChange"),B=Symbol.for("lit-nothing"),n=new WeakMap,w=x.createTreeWalker(x,129);function o(q,D){if(!L(q)||!q.hasOwnProperty("raw"))throw Error("invalid template strings array");return p!==void 0?p.createHTML(D):D}var e=(q,D)=>{let F=q.length-1,J=[],G,O=D===2?"<svg>":D===3?"<math>":"",K=U;for(let W=0;W<F;W++){let Q=q[W],Y,X,b=-1,A=0;while(A<Q.length&&(K.lastIndex=A,X=K.exec(Q),X!==null))A=K.lastIndex,K===U?X[1]==="!--"?K=m:X[1]!==void 0?K=a:X[2]!==void 0?(r.test(X[2])&&(G=RegExp("</"+X[2],"g")),K=$):X[3]!==void 0&&(K=$):K===$?X[0]===">"?(K=G??U,b=-1):X[1]===void 0?b=-2:(b=K.lastIndex-X[2].length,Y=X[1],K=X[3]===void 0?$:X[3]===\'"\'?l:c):K===l||K===c?K=$:K===m||K===a?K=U:(K=$,G=void 0);const _=K===$&&q[W+1].startsWith("/>")?" ":"";O+=K===U?Q+Kq:b>=0?(J.push(Y),Q.slice(0,b)+"$lit$"+Q.slice(b)+P+_):Q+P+(b===-2?W:_)}return[o(q,O+(q[F]||"<?>")+(D===2?"</svg>":D===3?"</math>":"")),J]};class g{constructor({strings:q,_$litType$:D},F){let J;this.parts=[];let G=0,O=0,K=q.length-1,W=this.parts,[Q,Y]=e(q,D);if(this.el=g.createElement(Q,F),w.currentNode=this.el.content,D===2||D===3){const X=this.el.content.firstChild;X.replaceWith(...X.childNodes)}while((J=w.nextNode())!==null&&W.length<K){if(J.nodeType===1){if(J.hasAttributes())for(const X of J.getAttributeNames())if(X.endsWith("$lit$")){const b=Y[O++],A=J.getAttribute(X).split(P),_=/([.?@])?(.*)/.exec(b);W.push({type:1,index:G,name:_[2],strings:A,ctor:_[1]==="."?R:_[1]==="?"?E:_[1]==="@"?d:I}),J.removeAttribute(X)}else X.startsWith(P)&&(W.push({type:6,index:G}),J.removeAttribute(X));if(r.test(J.tagName)){const X=J.textContent.split(P),b=X.length-1;if(b>0){J.textContent=y?y.emptyScript:"";for(let A=0;A<b;A++)J.append(X[A],C()),w.nextNode(),W.push({type:2,index:++G});J.append(X[b],C())}}}else if(J.nodeType===8)if(J.data===v)W.push({type:2,index:G});else{let X=-1;while((X=J.data.indexOf(P,X+1))!==-1)W.push({type:7,index:G}),X+=P.length-1}G++}}static createElement(q,D){const F=x.createElement("template");return F.innerHTML=q,F}}function z(q,D,F=q,J){if(D===V)return D;let G=J!==void 0?F._$Co?.[J]:F._$Cl,O=S(D)?void 0:D._$litDirective$;return G?.constructor!==O&&(G?._$AO?.(!1),O===void 0?G=void 0:(G=new O(q),G._$AT(q,F,J)),J!==void 0?(F._$Co??=[])[J]=G:F._$Cl=G),G!==void 0&&(D=z(q,G._$AS(q,D.values),G,J)),D}class j{constructor(q,D){this._$AV=[],this._$AN=void 0,this._$AD=q,this._$AM=D}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(q){const{el:{content:D},parts:F}=this._$AD,J=(q?.creationScope??x).importNode(D,!0);w.currentNode=J;let G=w.nextNode(),O=0,K=0,W=F[0];while(W!==void 0){if(O===W.index){let Q;W.type===2?Q=new H(G,G.nextSibling,this,q):W.type===1?Q=new W.ctor(G,W.name,W.strings,this,q):W.type===6&&(Q=new f(G,this,q)),this._$AV.push(Q),W=F[++K]}O!==W?.index&&(G=w.nextNode(),O++)}return w.currentNode=x,J}p(q){let D=0;for(const F of this._$AV)F!==void 0&&(F.strings!==void 0?(F._$AI(q,F,D),D+=F.strings.length-2):F._$AI(q[D])),D++}}class H{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(q,D,F,J){this.type=2,this._$AH=B,this._$AN=void 0,this._$AA=q,this._$AB=D,this._$AM=F,this.options=J,this._$Cv=J?.isConnected??!0}get parentNode(){let q=this._$AA.parentNode,D=this._$AM;return D!==void 0&&q?.nodeType===11&&(q=D.parentNode),q}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(q,D=this){q=z(this,q,D),S(q)?q===B||q==null||q===""?(this._$AH!==B&&this._$AR(),this._$AH=B):q!==this._$AH&&q!==V&&this._(q):q._$litType$!==void 0?this.$(q):q.nodeType!==void 0?this.T(q):h(q)?this.k(q):this._(q)}O(q){return this._$AA.parentNode.insertBefore(q,this._$AB)}T(q){this._$AH!==q&&(this._$AR(),this._$AH=this.O(q))}_(q){this._$AH!==B&&S(this._$AH)?this._$AA.nextSibling.data=q:this.T(x.createTextNode(q)),this._$AH=q}$(q){const{values:D,_$litType$:F}=q,J=typeof F=="number"?this._$AC(q):(F.el===void 0&&(F.el=g.createElement(o(F.h,F.h[0]),this.options)),F);if(this._$AH?._$AD===J)this._$AH.p(D);else{const G=new j(J,this),O=G.u(this.options);G.p(D),this.T(O),this._$AH=G}}_$AC(q){let D=n.get(q.strings);return D===void 0&&n.set(q.strings,D=new g(q)),D}k(q){L(this._$AH)||(this._$AH=[],this._$AR());let D=this._$AH,F,J=0;for(const G of q)J===D.length?D.push(F=new H(this.O(C()),this.O(C()),this,this.options)):F=D[J],F._$AI(G),J++;J<D.length&&(this._$AR(F&&F._$AB.nextSibling,J),D.length=J)}_$AR(q=this._$AA.nextSibling,D){for(this._$AP?.(!1,!0,D);q&&q!==this._$AB;){const F=q.nextSibling;q.remove(),q=F}}setConnected(q){this._$AM===void 0&&(this._$Cv=q,this._$AP?.(q))}}class I{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(q,D,F,J,G){this.type=1,this._$AH=B,this._$AN=void 0,this.element=q,this.name=D,this._$AM=J,this.options=G,F.length>2||F[0]!==""||F[1]!==""?(this._$AH=Array(F.length-1).fill(new String),this.strings=F):this._$AH=B}_$AI(q,D=this,F,J){let G=this.strings,O=!1;if(G===void 0)q=z(this,q,D,0),O=!S(q)||q!==this._$AH&&q!==V,O&&(this._$AH=q);else{let K=q,W,Q;for(q=G[0],W=0;W<G.length-1;W++)Q=z(this,K[F+W],D,W),Q===V&&(Q=this._$AH[W]),O||=!S(Q)||Q!==this._$AH[W],Q===B?q=B:q!==B&&(q+=(Q??"")+G[W+1]),this._$AH[W]=Q}O&&!J&&this.j(q)}j(q){q===B?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,q??"")}}class R extends I{constructor(){super(...arguments),this.type=3}j(q){this.element[this.name]=q===B?void 0:q}}class E extends I{constructor(){super(...arguments),this.type=4}j(q){this.element.toggleAttribute(this.name,!!q&&q!==B)}}class d extends I{constructor(q,D,F,J,G){super(q,D,F,J,G),this.type=5}_$AI(q,D=this){if((q=z(this,q,D,0)??B)===V)return;const F=this._$AH,J=q===B&&F!==B||q.capture!==F.capture||q.once!==F.once||q.passive!==F.passive,G=q!==B&&(F===B||J);J&&this.element.removeEventListener(this.name,this,F),G&&this.element.addEventListener(this.name,this,q),this._$AH=q}handleEvent(q){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,q):this._$AH.handleEvent(q)}}class f{constructor(q,D,F){this.element=q,this.type=6,this._$AN=void 0,this._$AM=D,this.options=F}get _$AU(){return this._$AM._$AU}_$AI(q){z(this,q)}}var Z={M:"$lit$",P,A:v,C:1,L:e,R:j,D:h,V:z,I:H,H:I,N:E,U:d,B:R,F:f},Oq=k.litHtmlPolyfillSupport;Oq?.(g,H),(k.litHtmlVersions??=[]).push("3.2.1");var i=(q,D,F)=>{let J=F?.renderBefore??D,G=J._$litPart$;if(G===void 0){const O=F?.renderBefore??null;J._$litPart$=G=new H(D.insertBefore(C(),O),O,void 0,F??{})}return G._$AI(q),G};var u=null,s={boundAttributeSuffix:Z.M,marker:Z.P,markerMatch:Z.A,HTML_RESULT:Z.C,getTemplateHtml:Z.L,overrideDirectiveResolve:(q,D)=>class extends q{_$AS(F,J){return D(this,J)}},patchDirectiveResolve:(q,D)=>{if(q.prototype._$AS!==D){u??=q.prototype._$AS.name;for(let F=q.prototype;F!==Object.prototype;F=Object.getPrototypeOf(F))if(F.hasOwnProperty(u))return void(F[u]=D);throw Error("Internal error: It is possible that both dev mode and production mode Lit was mixed together during SSR. Please comment on the issue: https://github.com/lit/lit/issues/4527")}},setDirectiveClass(q,D){q._$litDirective$=D},getAttributePartCommittedValue:(q,D,F)=>{let J=V;return q.j=(G)=>J=G,q._$AI(D,q,F),J},connectedDisconnectable:(q)=>({...q,_$AU:!0}),resolveDirective:Z.V,AttributePart:Z.H,PropertyPart:Z.B,BooleanAttributePart:Z.N,EventPart:Z.U,ElementPart:Z.F,TemplateInstance:Z.R,isIterable:Z.D,ChildPart:Z.I};var T={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6};var t=(q)=>q===null||typeof q!="object"&&typeof q!="function";var qq=(q,D)=>D===void 0?q?._$litType$!==void 0:q?._$litType$===D,Dq=(q)=>q?._$litType$?.h!=null;var Fq=(q)=>q.strings===void 0;var{TemplateInstance:Qq,isIterable:Wq,resolveDirective:Gq,ChildPart:N,ElementPart:Xq}=s,Jq=(q,D,F={})=>{if(D._$litPart$!==void 0)throw Error("container already contains a live render");let J,G,O,K=[],W=document.createTreeWalker(D,NodeFilter.SHOW_COMMENT),Q;while((Q=W.nextNode())!==null){const Y=Q.data;if(Y.startsWith("lit-part")){if(K.length===0&&J!==void 0)throw Error(`There must be only one root part per container. Found a part marker (${Q}) when we already have a root part marker (${G})`);O=Yq(q,Q,K,F),J===void 0&&(J=O),G??=Q}else if(Y.startsWith("lit-node"))Zq(Q,K,F);else if(Y.startsWith("/lit-part")){if(K.length===1&&O!==J)throw Error("internal error");O=Bq(Q,O,K)}}if(J===void 0){const Y=D instanceof ShadowRoot?"{container.host.localName}\'s shadow root":D instanceof DocumentFragment?"DocumentFragment":D.localName;console.error(`There should be exactly one root part in a render container, but we didn\'t find any in ${Y}.`)}D._$litPart$=J},Yq=(q,D,F,J)=>{let G,O;if(F.length===0)O=new N(D,null,void 0,J),G=q;else{const K=F[F.length-1];if(K.type==="template-instance")O=new N(D,null,K.instance,J),K.instance._$AV.push(O),G=K.result.values[K.instancePartIndex++],K.templatePartIndex++;else if(K.type==="iterable"){O=new N(D,null,K.part,J);const W=K.iterator.next();if(W.done)throw G=void 0,K.done=!0,Error("Unhandled shorter than expected iterable");G=W.value,K.part._$AH.push(O)}else O=new N(D,null,K.part,J)}if(G=Gq(O,G),G===V)F.push({part:O,type:"leaf"});else if(t(G))F.push({part:O,type:"leaf"}),O._$AH=G;else if(qq(G)){if(Dq(G))throw Error("compiled templates are not supported");const K="lit-part "+bq(G);if(D.data!==K)throw Error("Hydration value mismatch: Unexpected TemplateResult rendered to part");{const W=N.prototype._$AC(G),Q=new Qq(W,O);F.push({type:"template-instance",instance:Q,part:O,templatePartIndex:0,instancePartIndex:0,result:G}),O._$AH=Q}}else Wq(G)?(F.push({part:O,type:"iterable",value:G,iterator:G[Symbol.iterator](),done:!1}),O._$AH=[]):(F.push({part:O,type:"leaf"}),O._$AH=G??"");return O},Bq=(q,D,F)=>{if(D===void 0)throw Error("unbalanced part marker");D._$AB=q;const J=F.pop();if(J.type==="iterable"&&!J.iterator.next().done)throw Error("unexpected longer than expected iterable");if(F.length>0)return F[F.length-1].part},Zq=(q,D,F)=>{const J=/lit-node (\\d+)/.exec(q.data),G=Number.parseInt(J[1]),O=q.nextElementSibling;if(O===null)throw Error("could not find node for attribute parts");O.removeAttribute("defer-hydration");const K=D[D.length-1];if(K.type!=="template-instance")throw Error("Hydration value mismatch: Primitive found where TemplateResult expected. This usually occurs due to conditional rendering that resulted in a different value or template being rendered between the server and client.");{const W=K.instance;for(;;){const Q=W._$AD.parts[K.templatePartIndex];if(Q===void 0||Q.type!==T.ATTRIBUTE&&Q.type!==T.ELEMENT||Q.index!==G)break;if(Q.type===T.ATTRIBUTE){const Y=new Q.ctor(O,Q.name,Q.strings,K.instance,F),X=Fq(Y)?K.result.values[K.instancePartIndex]:K.result.values,b=!(Y.type===T.EVENT||Y.type===T.PROPERTY);Y._$AI(X,Y,K.instancePartIndex,b),K.instancePartIndex+=Q.strings.length-1,W._$AV.push(Y)}else{const Y=new Xq(O,K.instance,F);Gq(Y,K.result.values[K.instancePartIndex++]),W._$AV.push(Y)}K.templatePartIndex++}}},bq=(q)=>{const D=new Uint32Array(2).fill(5381);for(const J of q.strings)for(let G=0;G<J.length;G++)D[G%2]=33*D[G%2]^J.charCodeAt(G);const F=String.fromCharCode(...new Uint8Array(D.buffer));return btoa(F)};globalThis.litElementHydrateSupport=({LitElement:q})=>{const D=Object.getOwnPropertyDescriptor(Object.getPrototypeOf(q),"observedAttributes").get;Object.defineProperty(q,"observedAttributes",{get(){return[...D.call(this),"defer-hydration"]}});const F=q.prototype.attributeChangedCallback;q.prototype.attributeChangedCallback=function(K,W,Q){K==="defer-hydration"&&Q===null&&J.call(this),F.call(this,K,W,Q)};const J=q.prototype.connectedCallback;q.prototype.connectedCallback=function(){this.hasAttribute("defer-hydration")||J.call(this)};const G=q.prototype.createRenderRoot;q.prototype.createRenderRoot=function(){return this.shadowRoot?(this._$AG=!0,this.shadowRoot):G.call(this)};const O=Object.getPrototypeOf(q.prototype).update;q.prototype.update=function(K){const W=this.render();if(O.call(this,K),this._$AG){this._$AG=!1;for(let Q=0;Q<this.attributes.length;Q++){const Y=this.attributes[Q];if(Y.name.startsWith("hydrate-internals-")){const X=Y.name.slice(18);this.removeAttribute(X),this.removeAttribute(Y.name)}}Jq(W,this.renderRoot,this.renderOptions)}else i(W,this.renderRoot,this.renderOptions)}};';
@@ -0,0 +1,47 @@
1
+ /**
2
+ * This module contains the Lit renderer
3
+ * @module
4
+ */
5
+ import type { ComponentRenderInput, ComponentRenderResult, EcoComponent, EcoPagesElement, IntegrationRendererRenderOptions, RouteRendererBody } from '@ecopages/core';
6
+ import { IntegrationRenderer, type RenderToResponseContext } from '@ecopages/core/route-renderer/integration-renderer';
7
+ /**
8
+ * A renderer for the Lit integration.
9
+ */
10
+ export declare class LitRenderer extends IntegrationRenderer<EcoPagesElement> {
11
+ name: string;
12
+ /**
13
+ * Renders a Lit component boundary for component-level orchestration.
14
+ *
15
+ * Includes component-scoped dependency assets when declared.
16
+ */
17
+ renderComponent(input: ComponentRenderInput): Promise<ComponentRenderResult>;
18
+ private readonly ssrLazyPreloader;
19
+ /**
20
+ * Detects preload failures that are expected for browser-only modules.
21
+ *
22
+ * These errors are treated as non-fatal during SSR preload because some
23
+ * lazy client scripts intentionally depend on browser globals.
24
+ */
25
+ protected isExpectedSsrPreloadError(error: unknown): boolean;
26
+ /**
27
+ * Collects lazy script file paths eligible for SSR preloading.
28
+ *
29
+ * Only per-entry lazy script dependencies with `ssr: true` are collected.
30
+ * File-backed entries are required (`src` must be present);
31
+ * inline content lazy entries are intentionally skipped.
32
+ */
33
+ protected collectSsrPreloadScripts(components: Array<EcoComponent | undefined>): string[];
34
+ /**
35
+ * Preloads SSR-eligible lazy scripts to register custom elements before render.
36
+ */
37
+ protected preloadSsrLazyScripts(components: Array<EcoComponent | undefined>): Promise<void>;
38
+ /**
39
+ * Resolves the concrete JS entrypoint used for SSR preloading.
40
+ *
41
+ * Scripts are passed through the asset pipeline so preload imports can use
42
+ * the same processed output shape as runtime dependencies.
43
+ */
44
+ protected resolveSsrPreloadEntrypoint(scriptPath: string): Promise<string | null>;
45
+ render({ params, query, props, locals, metadata, Page, Layout, HtmlTemplate, }: IntegrationRendererRenderOptions): Promise<RouteRendererBody>;
46
+ renderToResponse<P = Record<string, unknown>>(view: EcoComponent<P>, props: P, ctx: RenderToResponseContext): Promise<Response>;
47
+ }
@@ -0,0 +1,155 @@
1
+ import { IntegrationRenderer } from "@ecopages/core/route-renderer/integration-renderer";
2
+ import { render } from "@lit-labs/ssr";
3
+ import { RenderResultReadable } from "@lit-labs/ssr/lib/render-result-readable.js";
4
+ import { unsafeHTML } from "lit/directives/unsafe-html.js";
5
+ import { LitSsrLazyPreloader } from "./lit-ssr-lazy-preloader.js";
6
+ import { PLUGIN_NAME } from "./lit.plugin.js";
7
+ class LitRenderer extends IntegrationRenderer {
8
+ name = PLUGIN_NAME;
9
+ /**
10
+ * Renders a Lit component boundary for component-level orchestration.
11
+ *
12
+ * Includes component-scoped dependency assets when declared.
13
+ */
14
+ async renderComponent(input) {
15
+ const component = input.component;
16
+ const props = input.children === void 0 ? input.props : { ...input.props, children: input.children };
17
+ const content = await component(props);
18
+ const html = String(content);
19
+ const hasDependencies = Boolean(input.component.config?.dependencies);
20
+ const canResolveAssets = typeof this.assetProcessingService?.processDependencies === "function";
21
+ const assets = hasDependencies && canResolveAssets ? await this.processComponentDependencies([input.component]) : void 0;
22
+ return {
23
+ html,
24
+ canAttachAttributes: true,
25
+ rootTag: this.getRootTagName(html),
26
+ integrationName: this.name,
27
+ assets
28
+ };
29
+ }
30
+ ssrLazyPreloader = new LitSsrLazyPreloader({
31
+ resolveDependencyPath: this.resolveDependencyPath.bind(this),
32
+ processDependencies: this.assetProcessingService?.processDependencies?.bind(this.assetProcessingService)
33
+ });
34
+ /**
35
+ * Detects preload failures that are expected for browser-only modules.
36
+ *
37
+ * These errors are treated as non-fatal during SSR preload because some
38
+ * lazy client scripts intentionally depend on browser globals.
39
+ */
40
+ isExpectedSsrPreloadError(error) {
41
+ return this.ssrLazyPreloader.isExpectedSsrPreloadError(error);
42
+ }
43
+ /**
44
+ * Collects lazy script file paths eligible for SSR preloading.
45
+ *
46
+ * Only per-entry lazy script dependencies with `ssr: true` are collected.
47
+ * File-backed entries are required (`src` must be present);
48
+ * inline content lazy entries are intentionally skipped.
49
+ */
50
+ collectSsrPreloadScripts(components) {
51
+ return this.ssrLazyPreloader.collectSsrPreloadScripts(components);
52
+ }
53
+ /**
54
+ * Preloads SSR-eligible lazy scripts to register custom elements before render.
55
+ */
56
+ async preloadSsrLazyScripts(components) {
57
+ await this.ssrLazyPreloader.preloadSsrLazyScripts(components);
58
+ }
59
+ /**
60
+ * Resolves the concrete JS entrypoint used for SSR preloading.
61
+ *
62
+ * Scripts are passed through the asset pipeline so preload imports can use
63
+ * the same processed output shape as runtime dependencies.
64
+ */
65
+ async resolveSsrPreloadEntrypoint(scriptPath) {
66
+ return this.ssrLazyPreloader.resolveSsrPreloadEntrypoint(scriptPath);
67
+ }
68
+ async render({
69
+ params,
70
+ query,
71
+ props,
72
+ locals,
73
+ metadata,
74
+ Page,
75
+ Layout,
76
+ HtmlTemplate
77
+ }) {
78
+ try {
79
+ await this.preloadSsrLazyScripts([Page, Layout]);
80
+ const pageContent = await Page({ params, query, ...props, locals });
81
+ const children = Layout ? await Layout(
82
+ {
83
+ children: pageContent,
84
+ locals
85
+ }
86
+ ) : pageContent;
87
+ const template = await HtmlTemplate({
88
+ metadata,
89
+ children: "<--content-->",
90
+ pageProps: props || {}
91
+ });
92
+ const [templateStart, templateEnd] = template.split("<--content-->");
93
+ const DOC_TYPE = this.DOC_TYPE;
94
+ function* streamBody() {
95
+ yield DOC_TYPE;
96
+ yield templateStart;
97
+ yield* render(unsafeHTML(children));
98
+ yield templateEnd;
99
+ }
100
+ return new RenderResultReadable(streamBody());
101
+ } catch (error) {
102
+ throw this.createRenderError("Error rendering page", error);
103
+ }
104
+ }
105
+ async renderToResponse(view, props, ctx) {
106
+ try {
107
+ const viewConfig = view.config;
108
+ const Layout = viewConfig?.layout;
109
+ await this.preloadSsrLazyScripts([view, Layout]);
110
+ const viewFn = view;
111
+ const pageContent = await viewFn(props);
112
+ if (ctx.partial) {
113
+ function* streamBody2() {
114
+ yield* render(unsafeHTML(pageContent));
115
+ }
116
+ const readable = new RenderResultReadable(streamBody2());
117
+ return this.createHtmlResponse(readable, ctx);
118
+ }
119
+ const DOC_TYPE = this.DOC_TYPE;
120
+ const children = Layout ? await Layout({ children: pageContent }) : pageContent;
121
+ const HtmlTemplate = await this.getHtmlTemplate();
122
+ const metadata = view.metadata ? await view.metadata({
123
+ params: {},
124
+ query: {},
125
+ props,
126
+ appConfig: this.appConfig
127
+ }) : this.appConfig.defaultMetadata;
128
+ await this.prepareViewDependencies(view, Layout);
129
+ const template = await HtmlTemplate({
130
+ metadata,
131
+ children: "<--content-->",
132
+ pageProps: props
133
+ });
134
+ const [templateStart, templateEnd] = template.split("<--content-->");
135
+ function* streamBody() {
136
+ yield DOC_TYPE;
137
+ yield templateStart;
138
+ yield* render(unsafeHTML(children));
139
+ yield templateEnd;
140
+ }
141
+ const stream = new RenderResultReadable(streamBody());
142
+ const transformedResponse = await this.htmlTransformer.transform(
143
+ new Response(stream, {
144
+ headers: { "Content-Type": "text/html" }
145
+ })
146
+ );
147
+ return this.createHtmlResponse(transformedResponse.body, ctx);
148
+ } catch (error) {
149
+ throw this.createRenderError("Error rendering view", error);
150
+ }
151
+ }
152
+ }
153
+ export {
154
+ LitRenderer
155
+ };
@@ -0,0 +1,210 @@
1
+ /**
2
+ * This module contains the Lit renderer
3
+ * @module
4
+ */
5
+
6
+ import type {
7
+ ComponentRenderInput,
8
+ ComponentRenderResult,
9
+ EcoComponent,
10
+ EcoPagesElement,
11
+ IntegrationRendererRenderOptions,
12
+ PageMetadataProps,
13
+ RouteRendererBody,
14
+ } from '@ecopages/core';
15
+ import { IntegrationRenderer, type RenderToResponseContext } from '@ecopages/core/route-renderer/integration-renderer';
16
+ import { render } from '@lit-labs/ssr';
17
+ import { RenderResultReadable } from '@lit-labs/ssr/lib/render-result-readable.js';
18
+ import { unsafeHTML } from 'lit/directives/unsafe-html.js';
19
+ import { LitSsrLazyPreloader } from './lit-ssr-lazy-preloader.ts';
20
+ import { PLUGIN_NAME } from './lit.plugin.ts';
21
+
22
+ /**
23
+ * A renderer for the Lit integration.
24
+ */
25
+ export class LitRenderer extends IntegrationRenderer<EcoPagesElement> {
26
+ override name = PLUGIN_NAME;
27
+
28
+ /**
29
+ * Renders a Lit component boundary for component-level orchestration.
30
+ *
31
+ * Includes component-scoped dependency assets when declared.
32
+ */
33
+ override async renderComponent(input: ComponentRenderInput): Promise<ComponentRenderResult> {
34
+ const component = input.component as (
35
+ props: Record<string, unknown>,
36
+ ) => Promise<EcoPagesElement> | EcoPagesElement;
37
+ const props = input.children === undefined ? input.props : { ...input.props, children: input.children };
38
+ const content = await component(props);
39
+ const html = String(content);
40
+ const hasDependencies = Boolean(input.component.config?.dependencies);
41
+ const canResolveAssets = typeof this.assetProcessingService?.processDependencies === 'function';
42
+ const assets =
43
+ hasDependencies && canResolveAssets
44
+ ? await this.processComponentDependencies([input.component])
45
+ : undefined;
46
+
47
+ return {
48
+ html,
49
+ canAttachAttributes: true,
50
+ rootTag: this.getRootTagName(html),
51
+ integrationName: this.name,
52
+ assets,
53
+ };
54
+ }
55
+
56
+ private readonly ssrLazyPreloader = new LitSsrLazyPreloader({
57
+ resolveDependencyPath: this.resolveDependencyPath.bind(this),
58
+ processDependencies: this.assetProcessingService?.processDependencies?.bind(this.assetProcessingService),
59
+ });
60
+
61
+ /**
62
+ * Detects preload failures that are expected for browser-only modules.
63
+ *
64
+ * These errors are treated as non-fatal during SSR preload because some
65
+ * lazy client scripts intentionally depend on browser globals.
66
+ */
67
+ protected isExpectedSsrPreloadError(error: unknown): boolean {
68
+ return this.ssrLazyPreloader.isExpectedSsrPreloadError(error);
69
+ }
70
+
71
+ /**
72
+ * Collects lazy script file paths eligible for SSR preloading.
73
+ *
74
+ * Only per-entry lazy script dependencies with `ssr: true` are collected.
75
+ * File-backed entries are required (`src` must be present);
76
+ * inline content lazy entries are intentionally skipped.
77
+ */
78
+ protected collectSsrPreloadScripts(components: Array<EcoComponent | undefined>): string[] {
79
+ return this.ssrLazyPreloader.collectSsrPreloadScripts(components);
80
+ }
81
+
82
+ /**
83
+ * Preloads SSR-eligible lazy scripts to register custom elements before render.
84
+ */
85
+ protected async preloadSsrLazyScripts(components: Array<EcoComponent | undefined>): Promise<void> {
86
+ await this.ssrLazyPreloader.preloadSsrLazyScripts(components);
87
+ }
88
+
89
+ /**
90
+ * Resolves the concrete JS entrypoint used for SSR preloading.
91
+ *
92
+ * Scripts are passed through the asset pipeline so preload imports can use
93
+ * the same processed output shape as runtime dependencies.
94
+ */
95
+ protected async resolveSsrPreloadEntrypoint(scriptPath: string): Promise<string | null> {
96
+ return this.ssrLazyPreloader.resolveSsrPreloadEntrypoint(scriptPath);
97
+ }
98
+
99
+ async render({
100
+ params,
101
+ query,
102
+ props,
103
+ locals,
104
+ metadata,
105
+ Page,
106
+ Layout,
107
+ HtmlTemplate,
108
+ }: IntegrationRendererRenderOptions): Promise<RouteRendererBody> {
109
+ try {
110
+ await this.preloadSsrLazyScripts([Page, Layout]);
111
+
112
+ const pageContent = await Page({ params, query, ...props, locals });
113
+ const children = Layout
114
+ ? await (Layout as (props: { children: EcoPagesElement } & Record<string, unknown>) => EcoPagesElement)(
115
+ {
116
+ children: pageContent,
117
+ locals,
118
+ },
119
+ )
120
+ : pageContent;
121
+
122
+ const template = (await HtmlTemplate({
123
+ metadata,
124
+ children: '<--content-->',
125
+ pageProps: props || {},
126
+ })) as string;
127
+
128
+ const [templateStart, templateEnd] = template.split('<--content-->');
129
+
130
+ const DOC_TYPE = this.DOC_TYPE;
131
+
132
+ function* streamBody() {
133
+ yield DOC_TYPE;
134
+ yield templateStart;
135
+ yield* render(unsafeHTML(children));
136
+ yield templateEnd;
137
+ }
138
+
139
+ return new RenderResultReadable(streamBody());
140
+ } catch (error) {
141
+ throw this.createRenderError('Error rendering page', error);
142
+ }
143
+ }
144
+
145
+ async renderToResponse<P = Record<string, unknown>>(
146
+ view: EcoComponent<P>,
147
+ props: P,
148
+ ctx: RenderToResponseContext,
149
+ ): Promise<Response> {
150
+ try {
151
+ const viewConfig = view.config;
152
+ const Layout = viewConfig?.layout as
153
+ | ((props: { children: EcoPagesElement } & Record<string, unknown>) => EcoPagesElement)
154
+ | undefined;
155
+
156
+ await this.preloadSsrLazyScripts([view as unknown as EcoComponent, Layout as unknown as EcoComponent]);
157
+
158
+ const viewFn = view as (props: P) => Promise<EcoPagesElement>;
159
+ const pageContent = await viewFn(props);
160
+
161
+ if (ctx.partial) {
162
+ function* streamBody() {
163
+ yield* render(unsafeHTML(pageContent));
164
+ }
165
+ const readable = new RenderResultReadable(streamBody());
166
+ return this.createHtmlResponse(readable as unknown as BodyInit, ctx);
167
+ }
168
+
169
+ const DOC_TYPE = this.DOC_TYPE;
170
+ const children = Layout ? await Layout({ children: pageContent }) : pageContent;
171
+
172
+ const HtmlTemplate = await this.getHtmlTemplate();
173
+ const metadata: PageMetadataProps = view.metadata
174
+ ? await view.metadata({
175
+ params: {},
176
+ query: {},
177
+ props: props as Record<string, unknown>,
178
+ appConfig: this.appConfig,
179
+ })
180
+ : this.appConfig.defaultMetadata;
181
+
182
+ await this.prepareViewDependencies(view, Layout as EcoComponent | undefined);
183
+
184
+ const template = (await HtmlTemplate({
185
+ metadata,
186
+ children: '<--content-->',
187
+ pageProps: props as Record<string, unknown>,
188
+ })) as string;
189
+
190
+ const [templateStart, templateEnd] = template.split('<--content-->');
191
+
192
+ function* streamBody() {
193
+ yield DOC_TYPE;
194
+ yield templateStart;
195
+ yield* render(unsafeHTML(children));
196
+ yield templateEnd;
197
+ }
198
+ const stream = new RenderResultReadable(streamBody());
199
+ const transformedResponse = await this.htmlTransformer.transform(
200
+ new Response(stream as any, {
201
+ headers: { 'Content-Type': 'text/html' },
202
+ }),
203
+ );
204
+
205
+ return this.createHtmlResponse(transformedResponse.body as BodyInit, ctx);
206
+ } catch (error) {
207
+ throw this.createRenderError('Error rendering view', error);
208
+ }
209
+ }
210
+ }
@@ -0,0 +1,41 @@
1
+ import type { EcoComponent } from '@ecopages/core';
2
+ import type { AssetDefinition } from '@ecopages/core/services/asset-processing-service';
3
+ type ProcessDependencies = (dependencies: AssetDefinition[], integrationName: string) => Promise<Array<{
4
+ filepath?: string;
5
+ }>>;
6
+ export interface LitSsrLazyPreloaderOptions {
7
+ resolveDependencyPath: (componentDir: string, sourcePath: string) => string;
8
+ processDependencies?: ProcessDependencies;
9
+ }
10
+ /**
11
+ * Encapsulates SSR lazy script preload behavior for Lit components.
12
+ *
13
+ * Collects `dependencies.scripts` lazy entries with `ssr: true`, resolves the
14
+ * processed entrypoint through the asset pipeline, and imports the module so
15
+ * custom elements are registered before SSR rendering.
16
+ */
17
+ export declare class LitSsrLazyPreloader {
18
+ private readonly resolveDependencyPath;
19
+ private readonly processDependencies?;
20
+ private readonly ssrPreloadedScripts;
21
+ private readonly ssrPreloadFailedScripts;
22
+ private readonly ssrPreloadEntrypointCache;
23
+ constructor({ resolveDependencyPath, processDependencies }: LitSsrLazyPreloaderOptions);
24
+ /**
25
+ * Detects preload failures that are expected for browser-only modules.
26
+ */
27
+ isExpectedSsrPreloadError(error: unknown): boolean;
28
+ /**
29
+ * Collects lazy script file paths eligible for SSR preloading.
30
+ */
31
+ collectSsrPreloadScripts(components: Array<EcoComponent | undefined>): string[];
32
+ /**
33
+ * Preloads SSR-eligible lazy scripts to register custom elements before render.
34
+ */
35
+ preloadSsrLazyScripts(components: Array<EcoComponent | undefined>): Promise<void>;
36
+ /**
37
+ * Resolves the concrete JS entrypoint used for SSR preloading.
38
+ */
39
+ resolveSsrPreloadEntrypoint(scriptPath: string): Promise<string | null>;
40
+ }
41
+ export {};
@@ -0,0 +1,149 @@
1
+ import { AssetFactory } from "@ecopages/core/services/asset-processing-service";
2
+ import path from "node:path";
3
+ import { pathToFileURL } from "node:url";
4
+ class LitSsrLazyPreloader {
5
+ resolveDependencyPath;
6
+ processDependencies;
7
+ ssrPreloadedScripts = /* @__PURE__ */ new Set();
8
+ ssrPreloadFailedScripts = /* @__PURE__ */ new Set();
9
+ ssrPreloadEntrypointCache = /* @__PURE__ */ new Map();
10
+ constructor({ resolveDependencyPath, processDependencies }) {
11
+ this.resolveDependencyPath = resolveDependencyPath;
12
+ this.processDependencies = processDependencies;
13
+ }
14
+ /**
15
+ * Detects preload failures that are expected for browser-only modules.
16
+ */
17
+ isExpectedSsrPreloadError(error) {
18
+ const errorMessage = error instanceof Error ? error.message : String(error);
19
+ const errorCode = typeof error === "object" && error !== null && "code" in error ? String(error.code ?? "") : "";
20
+ if (errorCode === "ERR_UNKNOWN_FILE_EXTENSION") {
21
+ return true;
22
+ }
23
+ return errorMessage.includes(`reading 'Element'`) || errorMessage.includes("window is not defined") || errorMessage.includes("document is not defined") || errorMessage.includes("navigator is not defined");
24
+ }
25
+ /**
26
+ * Collects lazy script file paths eligible for SSR preloading.
27
+ */
28
+ collectSsrPreloadScripts(components) {
29
+ const scriptPaths = /* @__PURE__ */ new Set();
30
+ const visitedConfigs = /* @__PURE__ */ new Set();
31
+ const collect = (component) => {
32
+ const config = component?.config;
33
+ if (!config || visitedConfigs.has(config)) {
34
+ return;
35
+ }
36
+ visitedConfigs.add(config);
37
+ const scriptEntries = config.dependencies?.scripts ?? [];
38
+ const componentFile = config.__eco?.file;
39
+ if (componentFile) {
40
+ const componentDir = path.dirname(componentFile);
41
+ for (const script of scriptEntries) {
42
+ if (typeof script === "string") {
43
+ continue;
44
+ }
45
+ if (!script.lazy || script.ssr !== true) {
46
+ continue;
47
+ }
48
+ if (!script.src) {
49
+ continue;
50
+ }
51
+ scriptPaths.add(this.resolveDependencyPath(componentDir, script.src));
52
+ }
53
+ }
54
+ if (config.layout) {
55
+ collect(config.layout);
56
+ }
57
+ for (const nestedComponent of config.dependencies?.components || []) {
58
+ collect(nestedComponent);
59
+ }
60
+ };
61
+ for (const component of components) {
62
+ collect(component);
63
+ }
64
+ return Array.from(scriptPaths);
65
+ }
66
+ /**
67
+ * Preloads SSR-eligible lazy scripts to register custom elements before render.
68
+ */
69
+ async preloadSsrLazyScripts(components) {
70
+ const scripts = this.collectSsrPreloadScripts(components);
71
+ if (scripts.length === 0) {
72
+ return;
73
+ }
74
+ await Promise.all(
75
+ scripts.filter((scriptPath) => {
76
+ if (this.ssrPreloadedScripts.has(scriptPath)) {
77
+ return false;
78
+ }
79
+ if (this.ssrPreloadFailedScripts.has(scriptPath)) {
80
+ return false;
81
+ }
82
+ return true;
83
+ }).map(async (scriptPath) => {
84
+ const preloadEntrypoint = await this.resolveSsrPreloadEntrypoint(scriptPath);
85
+ if (!preloadEntrypoint) {
86
+ this.ssrPreloadFailedScripts.add(scriptPath);
87
+ return;
88
+ }
89
+ try {
90
+ await import(pathToFileURL(preloadEntrypoint).href);
91
+ this.ssrPreloadedScripts.add(scriptPath);
92
+ } catch (error) {
93
+ this.ssrPreloadFailedScripts.add(scriptPath);
94
+ if (this.isExpectedSsrPreloadError(error)) {
95
+ if (process.env.ECOPAGES_DEBUG === "true") {
96
+ console.warn(
97
+ `[ecopages][lit] Skipping SSR preload for browser-only lazy script: ${scriptPath}`
98
+ );
99
+ }
100
+ return;
101
+ }
102
+ console.warn(`[ecopages][lit] Failed to preload lazy SSR script: ${scriptPath}`, error);
103
+ }
104
+ })
105
+ );
106
+ }
107
+ /**
108
+ * Resolves the concrete JS entrypoint used for SSR preloading.
109
+ */
110
+ async resolveSsrPreloadEntrypoint(scriptPath) {
111
+ const cachedEntrypoint = this.ssrPreloadEntrypointCache.get(scriptPath);
112
+ if (cachedEntrypoint) {
113
+ return cachedEntrypoint;
114
+ }
115
+ if (!this.processDependencies) {
116
+ return scriptPath;
117
+ }
118
+ try {
119
+ const processed = await this.processDependencies(
120
+ [
121
+ AssetFactory.createInlineFileScript({
122
+ filepath: scriptPath,
123
+ position: "head",
124
+ bundle: true,
125
+ attributes: {
126
+ type: "module",
127
+ defer: ""
128
+ }
129
+ })
130
+ ],
131
+ `lit-ssr-preload:${scriptPath}`
132
+ );
133
+ const entrypoint = processed[0]?.filepath;
134
+ if (!entrypoint) {
135
+ return scriptPath;
136
+ }
137
+ this.ssrPreloadEntrypointCache.set(scriptPath, entrypoint);
138
+ return entrypoint;
139
+ } catch (error) {
140
+ if (process.env.ECOPAGES_DEBUG === "true") {
141
+ console.warn(`[ecopages][lit] Failed to resolve SSR preload entrypoint for: ${scriptPath}`, error);
142
+ }
143
+ return scriptPath;
144
+ }
145
+ }
146
+ }
147
+ export {
148
+ LitSsrLazyPreloader
149
+ };
@@ -0,0 +1,202 @@
1
+ import type { EcoComponent, EcoComponentConfig } from '@ecopages/core';
2
+ import { AssetFactory } from '@ecopages/core/services/asset-processing-service';
3
+ import type { AssetDefinition } from '@ecopages/core/services/asset-processing-service';
4
+ import path from 'node:path';
5
+ import { pathToFileURL } from 'node:url';
6
+
7
+ type ProcessDependencies = (
8
+ dependencies: AssetDefinition[],
9
+ integrationName: string,
10
+ ) => Promise<Array<{ filepath?: string }>>;
11
+
12
+ export interface LitSsrLazyPreloaderOptions {
13
+ resolveDependencyPath: (componentDir: string, sourcePath: string) => string;
14
+ processDependencies?: ProcessDependencies;
15
+ }
16
+
17
+ /**
18
+ * Encapsulates SSR lazy script preload behavior for Lit components.
19
+ *
20
+ * Collects `dependencies.scripts` lazy entries with `ssr: true`, resolves the
21
+ * processed entrypoint through the asset pipeline, and imports the module so
22
+ * custom elements are registered before SSR rendering.
23
+ */
24
+ export class LitSsrLazyPreloader {
25
+ private readonly resolveDependencyPath: (componentDir: string, sourcePath: string) => string;
26
+ private readonly processDependencies?: ProcessDependencies;
27
+ private readonly ssrPreloadedScripts = new Set<string>();
28
+ private readonly ssrPreloadFailedScripts = new Set<string>();
29
+ private readonly ssrPreloadEntrypointCache = new Map<string, string>();
30
+
31
+ constructor({ resolveDependencyPath, processDependencies }: LitSsrLazyPreloaderOptions) {
32
+ this.resolveDependencyPath = resolveDependencyPath;
33
+ this.processDependencies = processDependencies;
34
+ }
35
+
36
+ /**
37
+ * Detects preload failures that are expected for browser-only modules.
38
+ */
39
+ isExpectedSsrPreloadError(error: unknown): boolean {
40
+ const errorMessage = error instanceof Error ? error.message : String(error);
41
+ const errorCode =
42
+ typeof error === 'object' && error !== null && 'code' in error
43
+ ? String((error as { code?: unknown }).code ?? '')
44
+ : '';
45
+
46
+ if (errorCode === 'ERR_UNKNOWN_FILE_EXTENSION') {
47
+ return true;
48
+ }
49
+
50
+ return (
51
+ errorMessage.includes(`reading 'Element'`) ||
52
+ errorMessage.includes('window is not defined') ||
53
+ errorMessage.includes('document is not defined') ||
54
+ errorMessage.includes('navigator is not defined')
55
+ );
56
+ }
57
+
58
+ /**
59
+ * Collects lazy script file paths eligible for SSR preloading.
60
+ */
61
+ collectSsrPreloadScripts(components: Array<EcoComponent | undefined>): string[] {
62
+ const scriptPaths = new Set<string>();
63
+ const visitedConfigs = new Set<EcoComponentConfig>();
64
+
65
+ const collect = (component?: EcoComponent) => {
66
+ const config = component?.config;
67
+ if (!config || visitedConfigs.has(config)) {
68
+ return;
69
+ }
70
+
71
+ visitedConfigs.add(config);
72
+
73
+ const scriptEntries = config.dependencies?.scripts ?? [];
74
+ const componentFile = config.__eco?.file;
75
+
76
+ if (componentFile) {
77
+ const componentDir = path.dirname(componentFile);
78
+ for (const script of scriptEntries) {
79
+ if (typeof script === 'string') {
80
+ continue;
81
+ }
82
+
83
+ if (!script.lazy || script.ssr !== true) {
84
+ continue;
85
+ }
86
+
87
+ if (!script.src) {
88
+ continue;
89
+ }
90
+
91
+ scriptPaths.add(this.resolveDependencyPath(componentDir, script.src));
92
+ }
93
+ }
94
+
95
+ if (config.layout) {
96
+ collect(config.layout);
97
+ }
98
+
99
+ for (const nestedComponent of config.dependencies?.components || []) {
100
+ collect(nestedComponent);
101
+ }
102
+ };
103
+
104
+ for (const component of components) {
105
+ collect(component);
106
+ }
107
+
108
+ return Array.from(scriptPaths);
109
+ }
110
+
111
+ /**
112
+ * Preloads SSR-eligible lazy scripts to register custom elements before render.
113
+ */
114
+ async preloadSsrLazyScripts(components: Array<EcoComponent | undefined>): Promise<void> {
115
+ const scripts = this.collectSsrPreloadScripts(components);
116
+ if (scripts.length === 0) {
117
+ return;
118
+ }
119
+
120
+ await Promise.all(
121
+ scripts
122
+ .filter((scriptPath) => {
123
+ if (this.ssrPreloadedScripts.has(scriptPath)) {
124
+ return false;
125
+ }
126
+ if (this.ssrPreloadFailedScripts.has(scriptPath)) {
127
+ return false;
128
+ }
129
+ return true;
130
+ })
131
+ .map(async (scriptPath) => {
132
+ const preloadEntrypoint = await this.resolveSsrPreloadEntrypoint(scriptPath);
133
+ if (!preloadEntrypoint) {
134
+ this.ssrPreloadFailedScripts.add(scriptPath);
135
+ return;
136
+ }
137
+
138
+ try {
139
+ await import(pathToFileURL(preloadEntrypoint).href);
140
+ this.ssrPreloadedScripts.add(scriptPath);
141
+ } catch (error) {
142
+ this.ssrPreloadFailedScripts.add(scriptPath);
143
+
144
+ if (this.isExpectedSsrPreloadError(error)) {
145
+ if (process.env.ECOPAGES_DEBUG === 'true') {
146
+ console.warn(
147
+ `[ecopages][lit] Skipping SSR preload for browser-only lazy script: ${scriptPath}`,
148
+ );
149
+ }
150
+ return;
151
+ }
152
+
153
+ console.warn(`[ecopages][lit] Failed to preload lazy SSR script: ${scriptPath}`, error);
154
+ }
155
+ }),
156
+ );
157
+ }
158
+
159
+ /**
160
+ * Resolves the concrete JS entrypoint used for SSR preloading.
161
+ */
162
+ async resolveSsrPreloadEntrypoint(scriptPath: string): Promise<string | null> {
163
+ const cachedEntrypoint = this.ssrPreloadEntrypointCache.get(scriptPath);
164
+ if (cachedEntrypoint) {
165
+ return cachedEntrypoint;
166
+ }
167
+
168
+ if (!this.processDependencies) {
169
+ return scriptPath;
170
+ }
171
+
172
+ try {
173
+ const processed = await this.processDependencies(
174
+ [
175
+ AssetFactory.createInlineFileScript({
176
+ filepath: scriptPath,
177
+ position: 'head',
178
+ bundle: true,
179
+ attributes: {
180
+ type: 'module',
181
+ defer: '',
182
+ },
183
+ }),
184
+ ],
185
+ `lit-ssr-preload:${scriptPath}`,
186
+ );
187
+
188
+ const entrypoint = processed[0]?.filepath;
189
+ if (!entrypoint) {
190
+ return scriptPath;
191
+ }
192
+
193
+ this.ssrPreloadEntrypointCache.set(scriptPath, entrypoint);
194
+ return entrypoint;
195
+ } catch (error) {
196
+ if (process.env.ECOPAGES_DEBUG === 'true') {
197
+ console.warn(`[ecopages][lit] Failed to resolve SSR preload entrypoint for: ${scriptPath}`, error);
198
+ }
199
+ return scriptPath;
200
+ }
201
+ }
202
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * This module contains the Lit plugin
3
+ * @module
4
+ */
5
+ import '@lit-labs/ssr/lib/install-global-dom-shim.js';
6
+ import './console';
7
+ import { IntegrationPlugin, type IntegrationPluginConfig } from '@ecopages/core/plugins/integration-plugin';
8
+ import { type AssetDefinition } from '@ecopages/core/services/asset-processing-service';
9
+ import { LitRenderer } from './lit-renderer.js';
10
+ /**
11
+ * The name of the Lit plugin
12
+ */
13
+ export declare const PLUGIN_NAME = "lit";
14
+ /**
15
+ * The Lit plugin class
16
+ * This plugin provides support for Lit components in Ecopages
17
+ */
18
+ export declare class LitPlugin extends IntegrationPlugin {
19
+ renderer: typeof LitRenderer;
20
+ constructor(options?: Omit<IntegrationPluginConfig, 'name'>);
21
+ getDependencies(): AssetDefinition[];
22
+ }
23
+ /**
24
+ * Factory function to create a Lit plugin instance
25
+ * @param options Configuration options for the Lit plugin
26
+ * @returns A new LitPlugin instance
27
+ */
28
+ export declare function litPlugin(options?: Omit<IntegrationPluginConfig, 'name'>): LitPlugin;
@@ -0,0 +1,52 @@
1
+ import "@lit-labs/ssr/lib/install-global-dom-shim.js";
2
+ import "./console";
3
+ import { IntegrationPlugin } from "@ecopages/core/plugins/integration-plugin";
4
+ import { AssetFactory } from "@ecopages/core/services/asset-processing-service";
5
+ import { litElementHydrateScript } from "./lit-element-hydrate.js";
6
+ import { LitRenderer } from "./lit-renderer.js";
7
+ const PLUGIN_NAME = "lit";
8
+ class LitPlugin extends IntegrationPlugin {
9
+ renderer = LitRenderer;
10
+ constructor(options) {
11
+ super({
12
+ name: PLUGIN_NAME,
13
+ extensions: [".lit.tsx"],
14
+ staticBuildStep: "fetch",
15
+ ...options
16
+ });
17
+ this.integrationDependencies.unshift(...this.getDependencies());
18
+ }
19
+ getDependencies() {
20
+ return [
21
+ /**
22
+ * BUG ALERT
23
+ * Due to an issue appeared in Bun 1.2.2, we need to use a workaround to import the hydrate script.
24
+ * This is a temporary solution until the issue is resolved.
25
+ * The litElementHydrateScript is the same file built on Bun 1.1.45.
26
+ * https://github.com/oven-sh/bun/issues/17180
27
+ *
28
+ * AssetFactory.createNodeModuleScript({
29
+ * position: 'head',
30
+ * importPath: '@lit-labs/ssr-client/lit-element-hydrate-support.js'
31
+ * })
32
+ */
33
+ AssetFactory.createInlineContentScript({
34
+ position: "head",
35
+ content: litElementHydrateScript,
36
+ bundle: false,
37
+ attributes: {
38
+ "data-eco-rerun": "true",
39
+ "data-eco-script-id": "lit-hydrate-support"
40
+ }
41
+ })
42
+ ];
43
+ }
44
+ }
45
+ function litPlugin(options) {
46
+ return new LitPlugin(options);
47
+ }
48
+ export {
49
+ LitPlugin,
50
+ PLUGIN_NAME,
51
+ litPlugin
52
+ };
@@ -0,0 +1,70 @@
1
+ /**
2
+ * This module contains the Lit plugin
3
+ * @module
4
+ */
5
+
6
+ import '@lit-labs/ssr/lib/install-global-dom-shim.js';
7
+ import './console';
8
+ import { IntegrationPlugin, type IntegrationPluginConfig } from '@ecopages/core/plugins/integration-plugin';
9
+ import { type AssetDefinition, AssetFactory } from '@ecopages/core/services/asset-processing-service';
10
+ import { litElementHydrateScript } from './lit-element-hydrate.ts';
11
+ import { LitRenderer } from './lit-renderer.ts';
12
+
13
+ /**
14
+ * The name of the Lit plugin
15
+ */
16
+ export const PLUGIN_NAME = 'lit';
17
+
18
+ /**
19
+ * The Lit plugin class
20
+ * This plugin provides support for Lit components in Ecopages
21
+ */
22
+ export class LitPlugin extends IntegrationPlugin {
23
+ renderer = LitRenderer;
24
+
25
+ constructor(options?: Omit<IntegrationPluginConfig, 'name'>) {
26
+ super({
27
+ name: PLUGIN_NAME,
28
+ extensions: ['.lit.tsx'],
29
+ staticBuildStep: 'fetch',
30
+ ...options,
31
+ });
32
+
33
+ this.integrationDependencies.unshift(...this.getDependencies());
34
+ }
35
+
36
+ getDependencies(): AssetDefinition[] {
37
+ return [
38
+ /**
39
+ * BUG ALERT
40
+ * Due to an issue appeared in Bun 1.2.2, we need to use a workaround to import the hydrate script.
41
+ * This is a temporary solution until the issue is resolved.
42
+ * The litElementHydrateScript is the same file built on Bun 1.1.45.
43
+ * https://github.com/oven-sh/bun/issues/17180
44
+ *
45
+ * AssetFactory.createNodeModuleScript({
46
+ * position: 'head',
47
+ * importPath: '@lit-labs/ssr-client/lit-element-hydrate-support.js'
48
+ * })
49
+ */
50
+ AssetFactory.createInlineContentScript({
51
+ position: 'head',
52
+ content: litElementHydrateScript,
53
+ bundle: false,
54
+ attributes: {
55
+ 'data-eco-rerun': 'true',
56
+ 'data-eco-script-id': 'lit-hydrate-support',
57
+ },
58
+ }),
59
+ ];
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Factory function to create a Lit plugin instance
65
+ * @param options Configuration options for the Lit plugin
66
+ * @returns A new LitPlugin instance
67
+ */
68
+ export function litPlugin(options?: Omit<IntegrationPluginConfig, 'name'>): LitPlugin {
69
+ return new LitPlugin(options);
70
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * This module contains StyledMixin
3
+ * It is used to add styles to a LitElement
4
+ * @module
5
+ */
6
+ import { type LitElement } from 'lit';
7
+ type Constructor<T> = new (...args: any[]) => T;
8
+ /**
9
+ * A mixin to add styles to a LitElement
10
+ * @param superClass - The class to mix into
11
+ * @param css - The styles to add
12
+ * @returns The class with the styles added
13
+ */
14
+ export declare const StyledMixin: <T extends Constructor<LitElement>>(superClass: T, css?: string[]) => Constructor<LitElement> & T;
15
+ export {};
@@ -0,0 +1,13 @@
1
+ import { unsafeCSS } from "lit";
2
+ const StyledMixin = (superClass, css = []) => {
3
+ class StyledMixinClass extends superClass {
4
+ static styles = [
5
+ superClass.styles ?? [],
6
+ ...css.map((styles) => unsafeCSS(styles))
7
+ ];
8
+ }
9
+ return StyledMixinClass;
10
+ };
11
+ export {
12
+ StyledMixin
13
+ };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * This module contains StyledMixin
3
+ * It is used to add styles to a LitElement
4
+ * @module
5
+ */
6
+ import { type LitElement, unsafeCSS } from 'lit';
7
+
8
+ type Constructor<T> = new (...args: any[]) => T;
9
+
10
+ /**
11
+ * A mixin to add styles to a LitElement
12
+ * @param superClass - The class to mix into
13
+ * @param css - The styles to add
14
+ * @returns The class with the styles added
15
+ */
16
+ export const StyledMixin = <T extends Constructor<LitElement>>(
17
+ superClass: T,
18
+ css: string[] = [],
19
+ ): Constructor<LitElement> & T => {
20
+ class StyledMixinClass extends superClass {
21
+ static styles = [
22
+ (superClass as unknown as typeof LitElement).styles ?? [],
23
+ ...css.map((styles) => unsafeCSS(styles)),
24
+ ];
25
+ }
26
+ return StyledMixinClass as Constructor<LitElement> & T;
27
+ };