Skip to content

Commit b99f51f

Browse files
Use Lit SSR to render the element page (#1375)
1 parent 75d9d29 commit b99f51f

File tree

6 files changed

+140
-62
lines changed

6 files changed

+140
-62
lines changed

package-lock.json

Lines changed: 75 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/catalog-server/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
"@google-cloud/firestore": "^6.0.0",
8383
"@js-temporal/polyfill": "^0.4.2",
8484
"@koa/router": "^12.0.0",
85+
"@lit-labs/ssr": "^2.2.3",
8586
"@types/koa__router": "^12.0.0",
8687
"@types/koa-bodyparser": "^4.3.8",
8788
"@types/natural": "^5.1.1",
@@ -92,6 +93,7 @@
9293
"firebase-admin": "^11.0.0",
9394
"graphql-helix": "^1.13.0",
9495
"koa-bodyparser": "^4.3.0",
96+
"lit": "^2.4.0",
9597
"natural": "^5.2.3",
9698
"node-fetch": "^3.2.3",
9799
"npm-registry-fetch": "^13.1.0",

packages/site-content/site/_includes/layouts/base.11ty.cjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ module.exports = {
99
const {renderPage} = await import(
1010
'@webcomponents/internal-site-server/lib/templates/base.js'
1111
);
12-
return renderPage(data);
12+
return [...renderPage(data)].join('');
1313
},
1414
};

packages/site-server/src/catalog/routes/element/element-route.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
* Copyright 2022 Google LLC
44
* SPDX-License-Identifier: Apache-2.0
55
*/
6-
6+
import {render} from '@lit-labs/ssr/lib/render-with-global-dom-shim.js';
77
import Router from '@koa/router';
88
import {gql} from '@apollo/client/core/index.js';
99
import {renderPage} from '../../../templates/base.js';
1010
import {renderElement} from './element-template.js';
1111
import {DefaultContext, DefaultState, ParameterizedContext} from 'koa';
12-
import { client } from '../../graphql.js';
12+
import {client} from '../../graphql.js';
13+
import {Readable} from 'stream';
1314

1415
export const handleElementRoute = async (
1516
context: ParameterizedContext<
@@ -76,15 +77,18 @@ export const handleElementRoute = async (
7677
throw new Error('Internal error');
7778
}
7879

79-
const content = renderElement({
80-
packageName: packageName,
81-
elementName: elementName,
82-
declarationReference: customElement.declaration,
83-
customElementExport: customElement.export,
84-
manifest: customElementsManifest,
85-
});
86-
87-
context.body = renderPage({title: `${packageName}/${elementName}`, content});
80+
context.body = Readable.from(renderPage({
81+
title: `${packageName}/${elementName}`,
82+
content: render(
83+
renderElement({
84+
packageName: packageName,
85+
elementName: elementName,
86+
declarationReference: customElement.declaration,
87+
customElementExport: customElement.export,
88+
manifest: customElementsManifest,
89+
})
90+
),
91+
}));
8892
context.type = 'html';
8993
context.status = 200;
9094
};

packages/site-server/src/catalog/routes/element/element-template.ts

Lines changed: 26 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
* SPDX-License-Identifier: BSD-3-Clause
55
*/
66

7+
import {html, TemplateResult} from 'lit';
78
import type {Package} from 'custom-elements-manifest/schema.js';
89
import {
910
getModule,
1011
parseReferenceString,
1112
resolveReference,
1213
normalizeModulePath,
1314
} from '@webcomponents/custom-elements-manifest-tools';
14-
import {escapeHTML} from '../../escape-html.js';
1515

1616
export const renderElement = ({
1717
packageName,
@@ -24,18 +24,18 @@ export const renderElement = ({
2424
declarationReference: string;
2525
customElementExport: string;
2626
manifest: Package;
27-
}): string => {
27+
}): TemplateResult => {
2828
const declarationRef = parseReferenceString(declarationReference);
2929
if (declarationRef.module === undefined) {
30-
return `
30+
return html`
3131
<h1>Error</h1>
3232
<p>${declarationReference} has no module</p>
3333
`;
3434
}
3535
const module = getModule(manifest, declarationRef.module);
3636

3737
if (module === undefined) {
38-
return `
38+
return html`
3939
<h1>Error</h1>
4040
<p>Module ${declarationRef.module} not found</p>
4141
`;
@@ -48,46 +48,35 @@ export const renderElement = ({
4848
packageName,
4949
''
5050
);
51-
console.log('elementDeclaration', declaration);
5251

5352
if (declaration === undefined || declaration.kind !== 'class') {
54-
return `
53+
return html`
5554
<h1>Error</h1>
5655
<h2>Element declaration not found</h2>
5756
`;
5857
}
5958

60-
return `
61-
<h1>${packageName}/${elementName}</h1>
62-
${declaration.description}
63-
<h2>Usage</h2>
64-
<pre><code>
59+
return html`
60+
<h1>${packageName}/${elementName}</h1>
61+
${declaration.description}
62+
<h2>Usage</h2>
63+
<pre><code>
6564
<!-- TODO: this is wrong. We need the jsExport in the db -->
66-
import {${declaration.name}} from '${
67-
declarationRef.package
68-
}/${normalizeModulePath(declarationRef.module)}';
65+
import {${declaration.name}} from '${declarationRef.package}/${normalizeModulePath(
66+
declarationRef.module
67+
)}';
6968
</code></pre>
70-
<h2>Fields</h2>
71-
<ul>
72-
${declaration.members
73-
?.filter((m) => m.kind === 'field')
74-
.map(
75-
(m) => `
76-
<li>${m.name}: ${escapeHTML(m.description)}</li>
77-
`
78-
)
79-
.join('\n')}
80-
</ul>
81-
<h2>Methods</h2>
82-
<ul>
83-
${declaration.members
84-
?.filter((m) => m.kind === 'method')
85-
.map(
86-
(m) => `
87-
<li>${m.name}: ${escapeHTML(m.description)}</li>
88-
`
89-
)
90-
.join('\n')}
91-
</ul>
92-
`;
69+
<h2>Fields</h2>
70+
<ul>
71+
${declaration.members
72+
?.filter((m) => m.kind === 'field')
73+
.map((m) => html` <li>${m.name}: ${m.description}</li> `)}
74+
</ul>
75+
<h2>Methods</h2>
76+
<ul>
77+
${declaration.members
78+
?.filter((m) => m.kind === 'method')
79+
.map((m) => html` <li>${m.name}: ${m.description}</li> `)}
80+
</ul>
81+
`;
9382
};

packages/site-server/src/templates/base.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
*/
66
import {escapeHTML} from '../catalog/escape-html.js';
77

8-
export const renderPage = (data: {
8+
export function* renderPage(data: {
99
scripts?: Array<string>;
1010
title?: string;
11-
content?: string;
12-
}) => {
13-
return `<!doctype html>
11+
content: string | Iterable<string>;
12+
}) {
13+
yield `<!doctype html>
1414
<html lang="en">
1515
<head>
1616
<meta charset="utf-8">
@@ -27,11 +27,15 @@ export const renderPage = (data: {
2727
compiled any process access out. DO_NOT_LAUNCH -->
2828
<script>
2929
window.process = {env: {NODE_ENV: 'development'}};
30-
</script>
31-
${(data.scripts ?? [])
32-
.map((s) => `<script type="module" src="${s}"></script>`)
33-
.join('\n')}
34-
<style>
30+
</script>`;
31+
32+
if (data.scripts !== undefined) {
33+
yield* data.scripts.map(
34+
(s) => `<script type="module" src="${s}"></script>`
35+
);
36+
}
37+
38+
yield `<style>
3539
body {
3640
margin: 0;
3741
--mdc-typography-font-family: 'Open Sans', Arial, Helvetica, sans-serif;
@@ -48,9 +52,14 @@ export const renderPage = (data: {
4852
<title>${escapeHTML(data.title)}</title>
4953
</head>
5054
<body>
51-
<wco-top-bar></wco-top-bar>
52-
${data.content}
55+
<wco-top-bar></wco-top-bar>`;
56+
if (typeof data.content === 'string') {
57+
yield data.content;
58+
} else {
59+
yield* data.content;
60+
}
61+
yield `
5362
</body>
5463
</html>
5564
`;
56-
};
65+
}

0 commit comments

Comments
 (0)