@ecopages/lit 0.2.0-beta.9 → 0.2.0-rc.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ecopages/lit",
3
- "version": "0.2.0-beta.9",
3
+ "version": "0.2.0-rc.1",
4
4
  "description": "Ecopages lit integration",
5
5
  "keywords": [
6
6
  "ecopages",
@@ -39,7 +39,7 @@
39
39
  "directory": "packages/integrations/lit"
40
40
  },
41
41
  "peerDependencies": {
42
- "@ecopages/core": "0.2.0-beta.9",
42
+ "@ecopages/core": "0.2.0-rc.1",
43
43
  "@lit-labs/ssr": "^3.3.0",
44
44
  "@lit-labs/ssr-client": "^1.1.7",
45
45
  "lit": "^3.2.1"
@@ -11,37 +11,59 @@ LitPlugin.setup()
11
11
  └─ LitStaticRenderSession.ensureWorker()
12
12
  └─ LitStaticRenderWorkerClient.start()
13
13
  └─ postMessage(init) ──► setupAppRuntimePlugins()
14
- installAppRuntimeBuildExecutor()
14
+ installBuildRuntime()
15
15
  RouteRendererFactory
16
16
 
17
+ LitPlugin.initializeRenderer()
18
+ └─ LitRenderer({ getRenderSession }) lazy accessor (not constructor snapshot)
19
+
17
20
  LitRenderer.execute() (main)
18
- └─ session.renderPageInWorker()
19
- └─ postMessage(render) ─────► RouteRendererFactory.execute()
20
- (no active session in worker)
21
+ └─ ensureIntegrationRuntimeActivated()
22
+ └─ getRenderSession()
23
+ ├─ locals present ──────────► super.execute() (in-process)
24
+ └─ session.renderPageInWorker()
25
+ └─ postMessage(render) ─────► RouteRendererFactory.execute()
26
+ (no active session in worker)
21
27
 
22
28
  beforeStaticExport
29
+ └─ ensureWorker() only when `renderSession` is still null
23
30
  └─ preloadStaticRoutes()
24
31
  └─ preload SSR lazy scripts for Lit pages
25
32
  ```
26
33
 
27
- `ECOPAGES_LIT_STATIC_RENDER_WORKER=true` in the worker environment prevents nested worker creation during `LitPlugin.setup()`.
34
+ `ECOPAGES_LIT_STATIC_RENDER_WORKER=true` in the worker environment prevents nested worker creation during `LitPlugin.setup()` and skips processor `.setup()` inside `setupAppRuntimePlugins` (main thread already prepared artifacts).
35
+
36
+ ## Ownership
37
+
38
+ | Concern | Owner |
39
+ | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
40
+ | Session + worker lifecycle | `LitPlugin` (`renderSession`) |
41
+ | Lazy session lookup | `LitRenderer` via `getRenderSession` |
42
+ | Worker identity | First `{ configModulePath, runtimeOrigin }` passed to `ensureWorker`; same identity is sticky; a later `ensureWorker` with a different identity disposes and recreates |
43
+
44
+ Renderers created before plugin `setup()` still use the worker after setup assigns the session, because `execute` activates the integration runtime then reads the accessor.
45
+
46
+ `beforeStaticExport` does not re-call `ensureWorker` when setup already created the session, so a different `context.baseUrl` at export time will not recreate an existing worker.
47
+
48
+ ## Locals policy
49
+
50
+ When `RouteRendererOptions.locals` is present, `LitRenderer.execute` forces the in-process path (`super.execute`). Request locals are not sent through the worker protocol (structured-clone risk and request-scoped data). Static export and routes without locals continue through the worker.
28
51
 
29
52
  ## Files
30
53
 
31
54
  | File | Role |
32
55
  | ------------------------------------ | --------------------------------------------------------------- |
33
- | `lit-static-render-session.ts` | Build-scoped session: worker lifecycle + SSR preload |
56
+ | `lit-static-render-session.ts` | Plugin-runtime-scoped session: worker lifecycle + SSR preload |
34
57
  | `lit-static-render-worker-client.ts` | Message protocol client |
35
58
  | `lit-static-render-worker.ts` | Worker entry (exported as `@ecopages/lit/static-render-worker`) |
36
59
  | `lit-static-render-protocol.ts` | Request/response message types |
37
- | `lit-static-render-coordinator.ts` | Active session pointer for `LitRenderer` |
38
60
 
39
61
  ## Protocol
40
62
 
41
- | Message | Direction | Purpose |
42
- | ------------------ | ------------- | --------------------------------------- |
43
- | `init` | main → worker | Load `eco.config.ts`, bootstrap runtime |
44
- | `ready` | worker → main | Worker initialized |
45
- | `render` | main → worker | Render one Lit page route to HTML |
46
- | `result` / `error` | worker → main | Render outcome |
47
- | `shutdown` | main → worker | Exit worker thread |
63
+ | Message | Direction | Purpose |
64
+ | ------------------ | ------------- | ----------------------------------------------------------------------------- |
65
+ | `init` | main → worker | Load `eco.config.ts`, bootstrap runtime (`configModulePath`, `runtimeOrigin`) |
66
+ | `ready` | worker → main | Worker initialized |
67
+ | `render` | main → worker | Render one Lit page route (`filePath`, `PageParams`, optional `PageQuery`) |
68
+ | `result` / `error` | worker → main | HTML body plus optional `cacheStrategy`, or an error message |
69
+ | `shutdown` | main → worker | Exit worker thread |
package/src/console.js CHANGED
@@ -1,9 +1,15 @@
1
+ "use strict";
1
2
  const originalConsoleWarn = console.warn;
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
+ */
2
10
  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);
11
+ if (messages.some((message) => typeof message === 'string' && message.includes("'CustomElementRegistry' already has"))) {
12
+ return;
13
+ }
14
+ originalConsoleWarn.apply(console, messages);
9
15
  };
package/src/dom-shim.js CHANGED
@@ -1,13 +1,14 @@
1
- import { installWindowOnGlobal } from "@lit-labs/ssr/lib/dom-shim.js";
2
- import "@lit-labs/ssr/lib/install-global-dom-shim.js";
3
- if (typeof globalThis.document?.createTreeWalker !== "function") {
4
- if (typeof globalThis.window === "undefined") {
5
- installWindowOnGlobal();
6
- } else {
7
- Object.defineProperty(globalThis.document, "createTreeWalker", {
8
- configurable: true,
9
- writable: true,
10
- value: () => ({})
11
- });
12
- }
1
+ import { installWindowOnGlobal } from '@lit-labs/ssr/lib/dom-shim.js';
2
+ import '@lit-labs/ssr/lib/install-global-dom-shim.js';
3
+ if (typeof globalThis.document?.createTreeWalker !== 'function') {
4
+ if (typeof globalThis.window === 'undefined') {
5
+ installWindowOnGlobal();
6
+ }
7
+ else {
8
+ Object.defineProperty(globalThis.document, 'createTreeWalker', {
9
+ configurable: true,
10
+ writable: true,
11
+ value: () => ({}),
12
+ });
13
+ }
13
14
  }
@@ -1,4 +1 @@
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
- };
1
+ export 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)}};';
@@ -4,18 +4,39 @@
4
4
  */
5
5
  import type { ComponentRenderInput, ComponentRenderResult, EcoComponent, EcoPagesElement, IntegrationRendererRenderOptions, RouteRenderResult, RouteRendererBody, RouteRendererOptions } from '@ecopages/core';
6
6
  import './dom-shim.js';
7
- import { IntegrationRenderer, type RenderToResponseContext } from '@ecopages/core/route-renderer/integration-renderer';
7
+ import { IntegrationRenderer, type RenderToResponseContext } from '@ecopages/core/route-renderer/orchestration/integration-renderer';
8
+ import type { LitStaticRenderSession } from './lit-static-render-session.js';
9
+ export type LitRendererOptions = ConstructorParameters<typeof IntegrationRenderer>[0] & {
10
+ /**
11
+ * Lazy session lookup owned by {@link LitPlugin}.
12
+ *
13
+ * @remarks
14
+ * Must not snapshot the session at construction time. Plugin `setup()` may
15
+ * assign the session after the renderer is created; `execute` activates the
16
+ * integration runtime then reads this accessor so worker dispatch still works.
17
+ */
18
+ getRenderSession?: () => LitStaticRenderSession | undefined;
19
+ };
8
20
  /**
9
21
  * A renderer for the Lit integration.
10
22
  */
11
23
  export declare class LitRenderer extends IntegrationRenderer<EcoPagesElement> {
12
24
  name: string;
25
+ private readonly getRenderSession?;
26
+ constructor(options: LitRendererOptions);
27
+ /**
28
+ * Renders a Lit page route, preferring the plugin worker when available.
29
+ *
30
+ * @remarks
31
+ * Activates the integration runtime before reading {@link getRenderSession}
32
+ * so a renderer constructed before plugin setup still sees the session.
33
+ * When `options.locals` is present, rendering stays in-process: request locals
34
+ * are not structured-cloned across the worker boundary.
35
+ */
13
36
  execute(options: RouteRendererOptions): Promise<RouteRenderResult>;
14
37
  private isFunctionComponent;
15
38
  private resolveQueuedForeignSubtreeChildren;
16
- private resolveQueuedForeignSubtreeHtml;
17
- protected shouldRenderPageComponent(): boolean;
18
- private isLitManagedComponent;
39
+ private renderLitQueuedForeignSubtreeChildren;
19
40
  /**
20
41
  * Renders a Lit component for component-level orchestration.
21
42
  *
@@ -53,6 +74,6 @@ export declare class LitRenderer extends IntegrationRenderer<EcoPagesElement> {
53
74
  * the same processed output shape as runtime dependencies.
54
75
  */
55
76
  protected resolveSsrPreloadEntrypoint(scriptPath: string): Promise<string | null>;
56
- render({ params, query, props, locals, metadata, Page, Layout, HtmlTemplate, }: IntegrationRendererRenderOptions): Promise<RouteRendererBody>;
77
+ render({ params, query, props, locals, metadata, Page, Layout, layoutEntries, HtmlTemplate, }: IntegrationRendererRenderOptions): Promise<RouteRendererBody>;
57
78
  renderToResponse<P = Record<string, unknown>>(view: EcoComponent<P>, props: P, ctx: RenderToResponseContext): Promise<Response>;
58
79
  }