astro/packages/integrations/lit/server.js
Matthew Phillips f5afaf2498
Support re-exporting astro components containing client components (#3625)
* Support re-exporting astro components containing client components

* Include metadata for markdown too

* Fix ssr, probably

* Inject post-build

* Remove tagName custom element test

* Allows using the constructor for lit elements

* Fix hoisted script scanning

* Pass through plugin context

* Get edge functions working in the edge tests

* Fix types for the edge function integration

* Upgrade the compiler

* Upgrade compiler version

* Better release notes for lit

* Update .changeset/unlucky-hairs-camp.md

Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com>

* Properly test that the draft was not rendered

* Prevent from rendering draft posts

* Add a changeset about the build perf improvement.

Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com>
2022-06-21 08:32:05 -04:00

80 lines
2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import './server-shim.js';
import '@lit-labs/ssr/lib/render-lit-html.js';
import { LitElementRenderer } from '@lit-labs/ssr/lib/lit-element-renderer.js';
function isCustomElementTag(name) {
return typeof name === 'string' && /-/.test(name);
}
function getCustomElementConstructor(name) {
if (typeof customElements !== 'undefined' && isCustomElementTag(name)) {
return customElements.get(name) || null;
} else if(typeof name === 'function') {
return name;
}
return null;
}
async function isLitElement(Component) {
const Ctr = getCustomElementConstructor(Component);
return !!(Ctr && Ctr._$litElement$);
}
async function check(Component, _props, _children) {
// Lit doesn't support getting a tagName from a Constructor at this time.
// So this must be a string at the moment.
return !!(await isLitElement(Component));
}
function* render(Component, attrs, children) {
let tagName = Component;
if(typeof tagName !== 'string') {
tagName = Component[Symbol.for('tagName')];
}
const instance = new LitElementRenderer(tagName);
// LitElementRenderer creates a new element instance, so copy over.
const Ctr = getCustomElementConstructor(tagName);
if (attrs) {
for (let [name, value] of Object.entries(attrs)) {
// check if this is a reactive property
if (name in Ctr.prototype) {
instance.setProperty(name, value);
} else {
instance.setAttribute(name, value);
}
}
}
instance.connectedCallback();
yield `<${tagName}`;
yield* instance.renderAttributes();
yield `>`;
const shadowContents = instance.renderShadow({});
if (shadowContents !== undefined) {
yield '<template shadowroot="open">';
yield* shadowContents;
yield '</template>';
}
yield children || ''; // dont print “undefined” as string
yield `</${tagName}>`;
}
async function renderToStaticMarkup(Component, props, children) {
let tagName = Component;
let out = '';
for (let chunk of render(tagName, props, children)) {
out += chunk;
}
return {
html: out,
};
}
export default {
check,
renderToStaticMarkup,
};