@ecopages/lit 0.2.0-alpha.11 → 0.2.0-alpha.12

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 CHANGED
@@ -14,6 +14,7 @@ All notable changes to `@ecopages/lit` are documented here.
14
14
 
15
15
  - Fixed mixed-template SSR composition, placeholder cleanup, lazy preload handling, and browser-router bootstrap reruns.
16
16
  - Routed Lit SSR through the static template pipeline so registered custom elements emit declarative shadow DOM.
17
+ - Fixed component-boundary SSR to inject serialized children through both direct Lit interpolation and repeated Lit child slots when Lit is hosted by other integrations.
17
18
 
18
19
  ### Refactoring
19
20
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ecopages/lit",
3
- "version": "0.2.0-alpha.11",
3
+ "version": "0.2.0-alpha.12",
4
4
  "description": "Ecopages lit integration",
5
5
  "keywords": [
6
6
  "ecopages",
@@ -31,7 +31,7 @@
31
31
  "directory": "packages/integrations/lit"
32
32
  },
33
33
  "peerDependencies": {
34
- "@ecopages/core": "0.2.0-alpha.11",
34
+ "@ecopages/core": "0.2.0-alpha.12",
35
35
  "@lit-labs/ssr": "^3.3.0",
36
36
  "@lit-labs/ssr-client": "^1.1.7",
37
37
  "lit": "^3.2.1"
@@ -3,14 +3,16 @@
3
3
  * @module
4
4
  */
5
5
  import type { ComponentRenderInput, ComponentRenderResult, EcoComponent, EcoPagesElement, IntegrationRendererRenderOptions, RouteRendererBody } from '@ecopages/core';
6
+ import '@lit-labs/ssr/lib/install-global-dom-shim.js';
6
7
  import { IntegrationRenderer, type RenderToResponseContext } from '@ecopages/core/route-renderer/integration-renderer';
7
8
  /**
8
9
  * A renderer for the Lit integration.
9
10
  */
10
11
  export declare class LitRenderer extends IntegrationRenderer<EcoPagesElement> {
11
12
  name: string;
12
- protected shouldRenderPageComponent(): boolean;
13
+ private normalizeDeclarativeShadowRootMarkup;
13
14
  private createRenderableMarkup;
15
+ protected shouldRenderPageComponent(): boolean;
14
16
  private renderMarkupToString;
15
17
  private renderValueToString;
16
18
  private isLitManagedComponent;
@@ -1,23 +1,31 @@
1
+ import "@lit-labs/ssr/lib/install-global-dom-shim.js";
1
2
  import { IntegrationRenderer } from "@ecopages/core/route-renderer/integration-renderer";
2
3
  import { render } from "@lit-labs/ssr";
3
4
  import { html as staticHtml, unsafeStatic } from "lit/static-html.js";
4
5
  import { LitSsrLazyPreloader } from "./lit-ssr-lazy-preloader.js";
5
6
  import { PLUGIN_NAME } from "./lit.plugin.js";
6
7
  const HTML_TEMPLATE_SLOT_MARKER = "<--content-->";
8
+ const COMPONENT_CHILDREN_SLOT_MARKER = "<!--eco-lit-component-children-->";
9
+ const ESCAPED_COMPONENT_CHILDREN_SLOT_MARKER = "&lt;!--eco-lit-component-children--&gt;";
10
+ const DOUBLE_ESCAPED_COMPONENT_CHILDREN_SLOT_MARKER = "&amp;lt;!--eco-lit-component-children--&amp;gt;";
11
+ const DUPLICATE_DECLARATIVE_SHADOW_ROOT_ATTRIBUTE = /\sshadowroot=(['"])(open|closed)\1(?=\sshadowrootmode=\1\2\1)/g;
7
12
  class LitRenderer extends IntegrationRenderer {
8
13
  name = PLUGIN_NAME;
9
- shouldRenderPageComponent() {
10
- return false;
14
+ normalizeDeclarativeShadowRootMarkup(markup) {
15
+ return markup.replace(DUPLICATE_DECLARATIVE_SHADOW_ROOT_ATTRIBUTE, "");
11
16
  }
12
17
  createRenderableMarkup(markup) {
13
18
  return staticHtml`${unsafeStatic(markup)}`;
14
19
  }
20
+ shouldRenderPageComponent() {
21
+ return false;
22
+ }
15
23
  async renderMarkupToString(markup) {
16
24
  let renderedHtml = "";
17
25
  for (const chunk of render(this.createRenderableMarkup(markup))) {
18
26
  renderedHtml += chunk;
19
27
  }
20
- return renderedHtml;
28
+ return this.normalizeDeclarativeShadowRootMarkup(renderedHtml);
21
29
  }
22
30
  async renderValueToString(value) {
23
31
  if (typeof value === "string") {
@@ -27,14 +35,23 @@ class LitRenderer extends IntegrationRenderer {
27
35
  for (const chunk of render(value)) {
28
36
  renderedHtml += chunk;
29
37
  }
30
- return renderedHtml;
38
+ return this.normalizeDeclarativeShadowRootMarkup(renderedHtml);
31
39
  }
32
40
  isLitManagedComponent(component) {
33
41
  return component?.config?.integration === this.name || component?.config?.__eco?.integration === this.name;
34
42
  }
35
43
  injectRenderedChildren(template, renderedChildren) {
44
+ for (const marker of [
45
+ COMPONENT_CHILDREN_SLOT_MARKER,
46
+ ESCAPED_COMPONENT_CHILDREN_SLOT_MARKER,
47
+ DOUBLE_ESCAPED_COMPONENT_CHILDREN_SLOT_MARKER
48
+ ]) {
49
+ if (template.includes(marker)) {
50
+ return template.split(marker).join(renderedChildren);
51
+ }
52
+ }
36
53
  if (template.includes(HTML_TEMPLATE_SLOT_MARKER)) {
37
- return template.replace(HTML_TEMPLATE_SLOT_MARKER, renderedChildren);
54
+ return template.split(HTML_TEMPLATE_SLOT_MARKER).join(renderedChildren);
38
55
  }
39
56
  if (template.includes("</body>")) {
40
57
  return template.replace("</body>", `${renderedChildren}</body>`);
@@ -73,9 +90,14 @@ class LitRenderer extends IntegrationRenderer {
73
90
  async renderComponent(input) {
74
91
  await this.preloadSsrLazyScripts([input.component]);
75
92
  const component = input.component;
76
- const props = input.children === void 0 ? input.props : { ...input.props, children: input.children };
93
+ const renderedChildren = input.children === void 0 ? void 0 : typeof input.children === "string" ? input.children : await this.renderValueToString(input.children);
94
+ const props = renderedChildren === void 0 ? input.props : {
95
+ ...input.props,
96
+ children: COMPONENT_CHILDREN_SLOT_MARKER
97
+ };
77
98
  const content = await component(props);
78
- const html = await this.renderValueToString(content);
99
+ const renderedHtml = await this.renderValueToString(content);
100
+ const html = renderedChildren === void 0 ? renderedHtml : this.injectRenderedChildren(renderedHtml, renderedChildren);
79
101
  const hasDependencies = Boolean(input.component.config?.dependencies);
80
102
  const canResolveAssets = typeof this.assetProcessingService?.processDependencies === "function";
81
103
  const assets = hasDependencies && canResolveAssets ? await this.processComponentDependencies([input.component]) : void 0;
@@ -148,7 +170,7 @@ class LitRenderer extends IntegrationRenderer {
148
170
  children: pageHtml,
149
171
  locals
150
172
  }) : pageHtml;
151
- const renderedChildren = this.isLitManagedComponent(HtmlTemplate) ? await this.renderMarkupToString(String(children)) : String(children);
173
+ const renderedChildren = this.normalizeDeclarativeShadowRootMarkup(String(children));
152
174
  return this.DOC_TYPE + await this.renderHtmlTemplate({
153
175
  HtmlTemplate,
154
176
  metadata,
@@ -180,10 +202,10 @@ class LitRenderer extends IntegrationRenderer {
180
202
  const pageContent = await viewFn(props);
181
203
  const pageHtml = await this.renderValueToString(pageContent);
182
204
  if (ctx.partial) {
183
- return await this.renderMarkupToString(pageHtml);
205
+ return this.normalizeDeclarativeShadowRootMarkup(pageHtml);
184
206
  }
185
207
  const children = Layout ? this.isLitManagedComponent(Layout) ? await this.renderValueToString(await Layout({ children: pageContent })) : await Layout({ children: pageHtml }) : pageHtml;
186
- const renderedChildren = this.isLitManagedComponent(HtmlTemplate) ? await this.renderMarkupToString(String(children)) : String(children);
208
+ const renderedChildren = this.normalizeDeclarativeShadowRootMarkup(String(children));
187
209
  return this.DOC_TYPE + await this.renderHtmlTemplate({
188
210
  HtmlTemplate,
189
211
  metadata: metadata ?? this.appConfig.defaultMetadata,
@@ -2,7 +2,6 @@
2
2
  * This module contains the Lit plugin
3
3
  * @module
4
4
  */
5
- import '@lit-labs/ssr/lib/install-global-dom-shim.js';
6
5
  import './console.js';
7
6
  import { IntegrationPlugin, type ComponentBoundaryPolicyInput, type IntegrationPluginConfig } from '@ecopages/core/plugins/integration-plugin';
8
7
  import { type AssetDefinition } from '@ecopages/core/services/asset-processing-service';
package/src/lit.plugin.js CHANGED
@@ -1,4 +1,3 @@
1
- import "@lit-labs/ssr/lib/install-global-dom-shim.js";
2
1
  import "./console.js";
3
2
  import {
4
3
  IntegrationPlugin