Improve renderer types (#69)
* Improve renderer types Looking at the render code I noticed that the Component rendering is not typed. This adds that, might help prevent a bug in the future. * Create the supported renderer type
This commit is contained in:
parent
4ccf4196e3
commit
185a267133
6 changed files with 20 additions and 10 deletions
|
@ -1,11 +1,16 @@
|
||||||
|
import type { Component as VueComponent } from 'vue';
|
||||||
|
import type { ComponentType as PreactComponent } from 'preact';
|
||||||
|
import type { ComponentType as ReactComponent } from 'react';
|
||||||
|
import type { SvelteComponent } from 'svelte';
|
||||||
|
|
||||||
export interface DynamicRenderContext {
|
export interface DynamicRenderContext {
|
||||||
componentUrl: string;
|
componentUrl: string;
|
||||||
componentExport: string;
|
componentExport: string;
|
||||||
frameworkUrls: string;
|
frameworkUrls: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ComponentRenderer {
|
export interface ComponentRenderer<T> {
|
||||||
renderStatic: StaticRendererGenerator;
|
renderStatic: StaticRendererGenerator<T>;
|
||||||
render(context: { root: string; Component: string; props: string; [key: string]: string }): string;
|
render(context: { root: string; Component: string; props: string; [key: string]: string }): string;
|
||||||
imports?: Record<string, string[]>;
|
imports?: Record<string, string[]>;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +20,9 @@ export interface ComponentContext {
|
||||||
root: string;
|
root: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type SupportedComponentRenderer = ComponentRenderer<VueComponent> |
|
||||||
|
ComponentRenderer<PreactComponent> | ComponentRenderer<ReactComponent> |
|
||||||
|
ComponentRenderer<SvelteComponent>;
|
||||||
export type StaticRenderer = (props: Record<string, any>, ...children: any[]) => Promise<string>;
|
export type StaticRenderer = (props: Record<string, any>, ...children: any[]) => Promise<string>;
|
||||||
export type StaticRendererGenerator<T = any> = (Component: T) => StaticRenderer;
|
export type StaticRendererGenerator<T = any> = (Component: T) => StaticRenderer;
|
||||||
export type DynamicRenderer = (props: Record<string, any>, ...children: any[]) => Promise<string>;
|
export type DynamicRenderer = (props: Record<string, any>, ...children: any[]) => Promise<string>;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { h, render } from 'preact';
|
import { h, render, ComponentType } from 'preact';
|
||||||
import { renderToString } from 'preact-render-to-string';
|
import { renderToString } from 'preact-render-to-string';
|
||||||
import type { ComponentRenderer } from '../../@types/renderer';
|
import type { ComponentRenderer } from '../../@types/renderer';
|
||||||
import { createRenderer } from './renderer';
|
import { createRenderer } from './renderer';
|
||||||
|
@ -6,7 +6,7 @@ import { createRenderer } from './renderer';
|
||||||
// This prevents tree-shaking of render.
|
// This prevents tree-shaking of render.
|
||||||
Function.prototype(render);
|
Function.prototype(render);
|
||||||
|
|
||||||
const Preact: ComponentRenderer = {
|
const Preact: ComponentRenderer<ComponentType> = {
|
||||||
renderStatic(Component) {
|
renderStatic(Component) {
|
||||||
return async (props, ...children) => renderToString(h(Component, props, ...children));
|
return async (props, ...children) => renderToString(h(Component, props, ...children));
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import type { ComponentRenderer } from '../../@types/renderer';
|
import type { ComponentRenderer } from '../../@types/renderer';
|
||||||
import React from 'react';
|
import React, { ComponentType } from 'react';
|
||||||
import ReactDOMServer from 'react-dom/server';
|
import ReactDOMServer from 'react-dom/server';
|
||||||
import { createRenderer } from './renderer';
|
import { createRenderer } from './renderer';
|
||||||
|
|
||||||
const ReactRenderer: ComponentRenderer = {
|
const ReactRenderer: ComponentRenderer<ComponentType> = {
|
||||||
renderStatic(Component) {
|
renderStatic(Component) {
|
||||||
return async (props, ...children) => ReactDOMServer.renderToString(React.createElement(Component, props, children));
|
return async (props, ...children) => ReactDOMServer.renderToString(React.createElement(Component, props, children));
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import type { ComponentRenderer, DynamicRenderContext, DynamicRendererGenerator, StaticRendererGenerator } from '../../@types/renderer';
|
import type { DynamicRenderContext, DynamicRendererGenerator, SupportedComponentRenderer, StaticRendererGenerator } from '../../@types/renderer';
|
||||||
|
|
||||||
/** Initialize Astro Component renderer for Static and Dynamic components */
|
/** Initialize Astro Component renderer for Static and Dynamic components */
|
||||||
export function createRenderer(renderer: ComponentRenderer) {
|
export function createRenderer(renderer: SupportedComponentRenderer) {
|
||||||
const _static: StaticRendererGenerator = (Component) => renderer.renderStatic(Component);
|
const _static: StaticRendererGenerator = (Component) => renderer.renderStatic(Component);
|
||||||
const _imports = (context: DynamicRenderContext) => {
|
const _imports = (context: DynamicRenderContext) => {
|
||||||
const values = Object.values(renderer.imports ?? {})
|
const values = Object.values(renderer.imports ?? {})
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import type { ComponentRenderer } from '../../@types/renderer';
|
import type { ComponentRenderer } from '../../@types/renderer';
|
||||||
|
import type { SvelteComponent } from 'svelte';
|
||||||
import { createRenderer } from './renderer';
|
import { createRenderer } from './renderer';
|
||||||
|
|
||||||
const SvelteRenderer: ComponentRenderer = {
|
const SvelteRenderer: ComponentRenderer<SvelteComponent> = {
|
||||||
renderStatic(Component) {
|
renderStatic(Component) {
|
||||||
return async (props, ...children) => {
|
return async (props, ...children) => {
|
||||||
const { html } = Component.render(props);
|
const { html } = Component.render(props);
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import type { ComponentRenderer } from '../../@types/renderer';
|
import type { ComponentRenderer } from '../../@types/renderer';
|
||||||
|
import type { Component as VueComponent } from 'vue';
|
||||||
import { renderToString } from '@vue/server-renderer';
|
import { renderToString } from '@vue/server-renderer';
|
||||||
import { createSSRApp, h as createElement } from 'vue';
|
import { createSSRApp, h as createElement } from 'vue';
|
||||||
import { createRenderer } from './renderer';
|
import { createRenderer } from './renderer';
|
||||||
|
|
||||||
const Vue: ComponentRenderer = {
|
const Vue: ComponentRenderer<VueComponent> = {
|
||||||
renderStatic(Component) {
|
renderStatic(Component) {
|
||||||
return async (props, ...children) => {
|
return async (props, ...children) => {
|
||||||
const app = createSSRApp({
|
const app = createSSRApp({
|
||||||
|
|
Loading…
Reference in a new issue