@ecopages/lit 0.2.0-alpha.13 → 0.2.0-alpha.15
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 +4 -0
- package/package.json +2 -2
- package/src/lit-renderer.d.ts +0 -6
- package/src/lit-renderer.js +14 -76
- package/src/utils/lit-html-rendering.d.ts +5 -0
- package/src/utils/lit-html-rendering.js +52 -0
package/CHANGELOG.md
CHANGED
|
@@ -17,3 +17,7 @@ All notable changes to `@ecopages/lit` are documented here.
|
|
|
17
17
|
### Tests
|
|
18
18
|
|
|
19
19
|
- Updated integration coverage for explicit boundary composition and Node and esbuild compatibility.
|
|
20
|
+
|
|
21
|
+
### Refactoring
|
|
22
|
+
|
|
23
|
+
- Moved Lit HTML serialization and child-slot reinjection mechanics into a dedicated utility so the renderer stays focused on preload and boundary orchestration.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ecopages/lit",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.15",
|
|
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.
|
|
34
|
+
"@ecopages/core": "0.2.0-alpha.15",
|
|
35
35
|
"@lit-labs/ssr": "^3.3.0",
|
|
36
36
|
"@lit-labs/ssr-client": "^1.1.7",
|
|
37
37
|
"lit": "^3.2.1"
|
package/src/lit-renderer.d.ts
CHANGED
|
@@ -12,14 +12,8 @@ export declare class LitRenderer extends IntegrationRenderer<EcoPagesElement> {
|
|
|
12
12
|
name: string;
|
|
13
13
|
private resolveQueuedBoundaryChildren;
|
|
14
14
|
private resolveQueuedBoundaryHtml;
|
|
15
|
-
private normalizeDeclarativeShadowRootMarkup;
|
|
16
|
-
private createRenderableMarkup;
|
|
17
15
|
protected shouldRenderPageComponent(): boolean;
|
|
18
|
-
private renderMarkupToString;
|
|
19
|
-
private renderValueToString;
|
|
20
16
|
private isLitManagedComponent;
|
|
21
|
-
private injectRenderedChildren;
|
|
22
|
-
private renderHtmlTemplate;
|
|
23
17
|
/**
|
|
24
18
|
* Renders a Lit component boundary for component-level orchestration.
|
|
25
19
|
*
|
package/src/lit-renderer.js
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import "@lit-labs/ssr/lib/install-global-dom-shim.js";
|
|
2
2
|
import { IntegrationRenderer } from "@ecopages/core/route-renderer/integration-renderer";
|
|
3
|
-
import { render } from "@lit-labs/ssr";
|
|
4
|
-
import { html as staticHtml, unsafeStatic } from "lit/static-html.js";
|
|
5
3
|
import { LitSsrLazyPreloader } from "./lit-ssr-lazy-preloader.js";
|
|
6
4
|
import { PLUGIN_NAME } from "./lit.plugin.js";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
import {
|
|
6
|
+
injectLitRenderedChildren,
|
|
7
|
+
LIT_COMPONENT_CHILDREN_SLOT_MARKER,
|
|
8
|
+
normalizeLitHtml,
|
|
9
|
+
renderLitValueToString
|
|
10
|
+
} from "./utils/lit-html-rendering.js";
|
|
12
11
|
class LitRenderer extends IntegrationRenderer {
|
|
13
12
|
name = PLUGIN_NAME;
|
|
14
13
|
async resolveQueuedBoundaryChildren(children, queuedResolutionsByToken, resolveToken) {
|
|
15
14
|
if (children === void 0) {
|
|
16
15
|
return void 0;
|
|
17
16
|
}
|
|
18
|
-
let renderedChildren = typeof children === "string" ? children : await
|
|
17
|
+
let renderedChildren = typeof children === "string" ? children : await renderLitValueToString(children);
|
|
19
18
|
renderedChildren = await this.resolveQueuedBoundaryTokens(
|
|
20
19
|
renderedChildren,
|
|
21
20
|
queuedResolutionsByToken,
|
|
@@ -45,73 +44,12 @@ class LitRenderer extends IntegrationRenderer {
|
|
|
45
44
|
assets: queuedBoundaryResolution.assets.length > 0 ? queuedBoundaryResolution.assets : void 0
|
|
46
45
|
};
|
|
47
46
|
}
|
|
48
|
-
normalizeDeclarativeShadowRootMarkup(markup) {
|
|
49
|
-
return markup.replace(DUPLICATE_DECLARATIVE_SHADOW_ROOT_ATTRIBUTE, "");
|
|
50
|
-
}
|
|
51
|
-
createRenderableMarkup(markup) {
|
|
52
|
-
return staticHtml`${unsafeStatic(markup)}`;
|
|
53
|
-
}
|
|
54
47
|
shouldRenderPageComponent() {
|
|
55
48
|
return false;
|
|
56
49
|
}
|
|
57
|
-
async renderMarkupToString(markup) {
|
|
58
|
-
let renderedHtml = "";
|
|
59
|
-
for (const chunk of render(this.createRenderableMarkup(markup))) {
|
|
60
|
-
renderedHtml += chunk;
|
|
61
|
-
}
|
|
62
|
-
return this.normalizeDeclarativeShadowRootMarkup(renderedHtml);
|
|
63
|
-
}
|
|
64
|
-
async renderValueToString(value) {
|
|
65
|
-
if (typeof value === "string") {
|
|
66
|
-
return await this.renderMarkupToString(value);
|
|
67
|
-
}
|
|
68
|
-
let renderedHtml = "";
|
|
69
|
-
for (const chunk of render(value)) {
|
|
70
|
-
renderedHtml += chunk;
|
|
71
|
-
}
|
|
72
|
-
return this.normalizeDeclarativeShadowRootMarkup(renderedHtml);
|
|
73
|
-
}
|
|
74
50
|
isLitManagedComponent(component) {
|
|
75
51
|
return component?.config?.integration === this.name || component?.config?.__eco?.integration === this.name;
|
|
76
52
|
}
|
|
77
|
-
injectRenderedChildren(template, renderedChildren) {
|
|
78
|
-
for (const marker of [
|
|
79
|
-
COMPONENT_CHILDREN_SLOT_MARKER,
|
|
80
|
-
ESCAPED_COMPONENT_CHILDREN_SLOT_MARKER,
|
|
81
|
-
DOUBLE_ESCAPED_COMPONENT_CHILDREN_SLOT_MARKER
|
|
82
|
-
]) {
|
|
83
|
-
if (template.includes(marker)) {
|
|
84
|
-
return template.split(marker).join(renderedChildren);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (template.includes(HTML_TEMPLATE_SLOT_MARKER)) {
|
|
88
|
-
return template.split(HTML_TEMPLATE_SLOT_MARKER).join(renderedChildren);
|
|
89
|
-
}
|
|
90
|
-
if (template.includes("</body>")) {
|
|
91
|
-
return template.replace("</body>", `${renderedChildren}</body>`);
|
|
92
|
-
}
|
|
93
|
-
if (template.includes("</html>")) {
|
|
94
|
-
return template.replace("</html>", `${renderedChildren}</html>`);
|
|
95
|
-
}
|
|
96
|
-
return `${template}${renderedChildren}`;
|
|
97
|
-
}
|
|
98
|
-
async renderHtmlTemplate(options) {
|
|
99
|
-
if (!options.isLitManagedHtmlTemplate) {
|
|
100
|
-
return String(
|
|
101
|
-
await options.HtmlTemplate({
|
|
102
|
-
metadata: options.metadata,
|
|
103
|
-
children: options.renderedChildren,
|
|
104
|
-
pageProps: options.pageProps
|
|
105
|
-
})
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
const template = await options.HtmlTemplate({
|
|
109
|
-
metadata: options.metadata,
|
|
110
|
-
children: HTML_TEMPLATE_SLOT_MARKER,
|
|
111
|
-
pageProps: options.pageProps
|
|
112
|
-
});
|
|
113
|
-
return this.injectRenderedChildren(String(template), options.renderedChildren);
|
|
114
|
-
}
|
|
115
53
|
/**
|
|
116
54
|
* Renders a Lit component boundary for component-level orchestration.
|
|
117
55
|
*
|
|
@@ -126,18 +64,18 @@ class LitRenderer extends IntegrationRenderer {
|
|
|
126
64
|
const component = input.component;
|
|
127
65
|
let renderedChildren;
|
|
128
66
|
if (input.children !== void 0) {
|
|
129
|
-
renderedChildren = typeof input.children === "string" ? input.children : await
|
|
67
|
+
renderedChildren = typeof input.children === "string" ? input.children : await renderLitValueToString(input.children);
|
|
130
68
|
}
|
|
131
69
|
let props = input.props;
|
|
132
70
|
if (renderedChildren !== void 0) {
|
|
133
71
|
props = {
|
|
134
72
|
...input.props,
|
|
135
|
-
children:
|
|
73
|
+
children: LIT_COMPONENT_CHILDREN_SLOT_MARKER
|
|
136
74
|
};
|
|
137
75
|
}
|
|
138
76
|
const content = await component(props);
|
|
139
|
-
const renderedHtml = await
|
|
140
|
-
const html = renderedChildren === void 0 ? renderedHtml :
|
|
77
|
+
const renderedHtml = await renderLitValueToString(content);
|
|
78
|
+
const html = renderedChildren === void 0 ? renderedHtml : injectLitRenderedChildren(renderedHtml, renderedChildren);
|
|
141
79
|
const queuedBoundaryResolution = await this.resolveQueuedBoundaryHtml(
|
|
142
80
|
html,
|
|
143
81
|
this.getQueuedBoundaryRuntime(input)
|
|
@@ -229,7 +167,7 @@ class LitRenderer extends IntegrationRenderer {
|
|
|
229
167
|
htmlTemplate: HtmlTemplate,
|
|
230
168
|
metadata,
|
|
231
169
|
pageProps: props || {},
|
|
232
|
-
transformDocumentHtml:
|
|
170
|
+
transformDocumentHtml: normalizeLitHtml
|
|
233
171
|
});
|
|
234
172
|
} catch (error) {
|
|
235
173
|
throw this.createRenderError("Error rendering page", error);
|
|
@@ -242,7 +180,7 @@ class LitRenderer extends IntegrationRenderer {
|
|
|
242
180
|
view,
|
|
243
181
|
props,
|
|
244
182
|
ctx,
|
|
245
|
-
transformHtml:
|
|
183
|
+
transformHtml: normalizeLitHtml
|
|
246
184
|
});
|
|
247
185
|
}
|
|
248
186
|
const viewConfig = view.config;
|
|
@@ -270,7 +208,7 @@ class LitRenderer extends IntegrationRenderer {
|
|
|
270
208
|
});
|
|
271
209
|
this.appendProcessedDependencies(pageRender.assets, layoutRender?.assets, documentRender.assets);
|
|
272
210
|
const body = await this.finalizeResolvedHtml({
|
|
273
|
-
html: `${this.DOC_TYPE}${
|
|
211
|
+
html: `${this.DOC_TYPE}${normalizeLitHtml(documentRender.html)}`,
|
|
274
212
|
partial: false
|
|
275
213
|
});
|
|
276
214
|
return this.createHtmlResponse(body, ctx);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const LIT_HTML_TEMPLATE_SLOT_MARKER = "<--content-->";
|
|
2
|
+
export declare const LIT_COMPONENT_CHILDREN_SLOT_MARKER = "<!--eco-lit-component-children-->";
|
|
3
|
+
export declare function normalizeLitHtml(markup: string): string;
|
|
4
|
+
export declare function injectLitRenderedChildren(template: string, renderedChildren: string): string;
|
|
5
|
+
export declare function renderLitValueToString(value: unknown): Promise<string>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { render } from "@lit-labs/ssr";
|
|
2
|
+
import { html as staticHtml, unsafeStatic } from "lit/static-html.js";
|
|
3
|
+
const LIT_HTML_TEMPLATE_SLOT_MARKER = "<--content-->";
|
|
4
|
+
const LIT_COMPONENT_CHILDREN_SLOT_MARKER = "<!--eco-lit-component-children-->";
|
|
5
|
+
const ESCAPED_COMPONENT_CHILDREN_SLOT_MARKER = "<!--eco-lit-component-children-->";
|
|
6
|
+
const DOUBLE_ESCAPED_COMPONENT_CHILDREN_SLOT_MARKER = "&lt;!--eco-lit-component-children--&gt;";
|
|
7
|
+
const DUPLICATE_DECLARATIVE_SHADOW_ROOT_ATTRIBUTE = /\sshadowroot=(['"])(open|closed)\1(?=\sshadowrootmode=\1\2\1)/g;
|
|
8
|
+
function normalizeLitHtml(markup) {
|
|
9
|
+
return markup.replace(DUPLICATE_DECLARATIVE_SHADOW_ROOT_ATTRIBUTE, "");
|
|
10
|
+
}
|
|
11
|
+
function injectLitRenderedChildren(template, renderedChildren) {
|
|
12
|
+
for (const marker of [
|
|
13
|
+
LIT_COMPONENT_CHILDREN_SLOT_MARKER,
|
|
14
|
+
ESCAPED_COMPONENT_CHILDREN_SLOT_MARKER,
|
|
15
|
+
DOUBLE_ESCAPED_COMPONENT_CHILDREN_SLOT_MARKER
|
|
16
|
+
]) {
|
|
17
|
+
if (template.includes(marker)) {
|
|
18
|
+
return template.split(marker).join(renderedChildren);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (template.includes(LIT_HTML_TEMPLATE_SLOT_MARKER)) {
|
|
22
|
+
return template.split(LIT_HTML_TEMPLATE_SLOT_MARKER).join(renderedChildren);
|
|
23
|
+
}
|
|
24
|
+
if (template.includes("</body>")) {
|
|
25
|
+
return template.replace("</body>", `${renderedChildren}</body>`);
|
|
26
|
+
}
|
|
27
|
+
if (template.includes("</html>")) {
|
|
28
|
+
return template.replace("</html>", `${renderedChildren}</html>`);
|
|
29
|
+
}
|
|
30
|
+
return `${template}${renderedChildren}`;
|
|
31
|
+
}
|
|
32
|
+
async function renderLitValueToString(value) {
|
|
33
|
+
if (typeof value === "string") {
|
|
34
|
+
let renderedHtml2 = "";
|
|
35
|
+
for (const chunk of render(staticHtml`${unsafeStatic(value)}`)) {
|
|
36
|
+
renderedHtml2 += chunk;
|
|
37
|
+
}
|
|
38
|
+
return normalizeLitHtml(renderedHtml2);
|
|
39
|
+
}
|
|
40
|
+
let renderedHtml = "";
|
|
41
|
+
for (const chunk of render(value)) {
|
|
42
|
+
renderedHtml += chunk;
|
|
43
|
+
}
|
|
44
|
+
return normalizeLitHtml(renderedHtml);
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
LIT_COMPONENT_CHILDREN_SLOT_MARKER,
|
|
48
|
+
LIT_HTML_TEMPLATE_SLOT_MARKER,
|
|
49
|
+
injectLitRenderedChildren,
|
|
50
|
+
normalizeLitHtml,
|
|
51
|
+
renderLitValueToString
|
|
52
|
+
};
|