From 6af46c9d9c7ff491e80bbae7460ce351cd18f69f Mon Sep 17 00:00:00 2001 From: nicholasrice Date: Wed, 4 May 2022 16:17:38 -0700 Subject: [PATCH] adds api extractor and configures exports. Also removes entrypoints to certain incomplete features --- .../fast-ssr/api-extractor.json | 9 +++ .../fast-ssr/docs/api-report.md | 62 ++++++++++++++++ packages/web-components/fast-ssr/package.json | 12 +++- .../elemenent-renderer.spec.ts | 4 +- .../src/element-renderer/element-renderer.ts | 6 ++ .../web-components/fast-ssr/src/exports.ts | 30 ++++---- .../fast-ssr/src/styles/style-renderer.ts | 10 ++- .../template-renderer.spec.ts | 6 +- .../template-renderer/template-renderer.ts | 72 +++++++++---------- 9 files changed, 148 insertions(+), 63 deletions(-) create mode 100644 packages/web-components/fast-ssr/api-extractor.json create mode 100644 packages/web-components/fast-ssr/docs/api-report.md diff --git a/packages/web-components/fast-ssr/api-extractor.json b/packages/web-components/fast-ssr/api-extractor.json new file mode 100644 index 00000000000..eedc82e737f --- /dev/null +++ b/packages/web-components/fast-ssr/api-extractor.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "extends": "../../../api-extractor.json", + "mainEntryPointFilePath": "./dist/dts/exports.d.ts", + "dtsRollup": { + "enabled": true, + "betaTrimmedFilePath": "./dist/fast-ssr.d.ts" + } +} \ No newline at end of file diff --git a/packages/web-components/fast-ssr/docs/api-report.md b/packages/web-components/fast-ssr/docs/api-report.md new file mode 100644 index 00000000000..51c8333c316 --- /dev/null +++ b/packages/web-components/fast-ssr/docs/api-report.md @@ -0,0 +1,62 @@ +## API Report File for "@microsoft/fast-ssr" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { Binding } from '@microsoft/fast-element'; +import { ComposableStyles } from '@microsoft/fast-element'; +import { Constructable } from '@microsoft/fast-element'; +import { ElementRenderer } from '@lit-labs/ssr'; +import { ExecutionContext } from '@microsoft/fast-element'; +import { FASTElement } from '@microsoft/fast-element'; +import { RenderInfo } from '@lit-labs/ssr'; +import { ViewBehaviorFactory } from '@microsoft/fast-element'; +import { ViewTemplate } from '@microsoft/fast-element'; + +// @beta +export type ComponentDOMEmissionMode = "shadow"; + +// @beta +export abstract class FASTElementRenderer extends ElementRenderer { + constructor(tagName: string); + attributeChangedCallback(name: string, old: string | null, value: string | null): void; + connectedCallback(): void; + readonly element: FASTElement; + static matchesClass(ctor: typeof HTMLElement): boolean; + renderLight(renderInfo: RenderInfo): IterableIterator; + renderShadow(renderInfo: RenderInfo): IterableIterator; + protected abstract styleRenderer: StyleRenderer; + protected abstract templateRenderer: TemplateRenderer; +} + +// @beta +function fastSSR(): { + templateRenderer: TemplateRenderer; + elementRenderer: typeof FASTElementRenderer; + defaultRenderInfo: RenderInfo; +}; +export default fastSSR; + +// @beta +export interface StyleRenderer { + render(styles: ComposableStyles): string; +} + +// @beta +export class TemplateRenderer { + readonly componentDOMEmissionMode: ComponentDOMEmissionMode; + render(template: ViewTemplate | string, renderInfo: RenderInfo, source?: unknown, context?: ExecutionContext): IterableIterator; + // Warning: (ae-forgotten-export) The symbol "Op" needs to be exported by the entry point exports.d.ts + // + // @internal + renderOpCodes(codes: Op[], renderInfo: RenderInfo, source: unknown, context: ExecutionContext): IterableIterator; + // Warning: (ae-forgotten-export) The symbol "ViewBehaviorFactoryRenderer" needs to be exported by the entry point exports.d.ts + // + // @internal + withViewBehaviorFactoryRenderers(...renderers: ViewBehaviorFactoryRenderer[]): void; +} + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/web-components/fast-ssr/package.json b/packages/web-components/fast-ssr/package.json index 5b32fb3c1ea..78306a340f9 100644 --- a/packages/web-components/fast-ssr/package.json +++ b/packages/web-components/fast-ssr/package.json @@ -16,7 +16,9 @@ }, "scripts": { "clean": "tsc -b --clean src", - "build": "tsc -b src", + "build": "tsc -b src && yarn doc", + "doc": "api-extractor run --local", + "doc:ci": "api-extractor run", "prepare": "yarn run clean && yarn run build", "build-server": "tsc -b server", "eslint": "eslint . --ext .ts", @@ -31,9 +33,12 @@ }, "description": "A package for rendering FAST components outside the browser.", "main": "./dist/esm/exports.js", - "types": "./dist/dts/exports.d.ts", + "types": "./dist/fast-ssr.d.ts", "exports": { - "." : "./dist/esm/exports.js", + "." : { + "default": "./dist/esm/exports.js", + "types": "./dist/fast-ssr.d.ts" + }, "./install-dom-shim": "./dist/esm/dom-shim.js" }, "private": true, @@ -44,6 +49,7 @@ "tslib": "^2.4.0" }, "devDependencies": { + "@microsoft/api-extractor": "7.23.0", "@playwright/test": "^1.20.1", "@types/express": "^4.17.13", "@types/node": "^17.0.17", diff --git a/packages/web-components/fast-ssr/src/element-renderer/elemenent-renderer.spec.ts b/packages/web-components/fast-ssr/src/element-renderer/elemenent-renderer.spec.ts index 7dc3dc3f769..7951ae0c325 100644 --- a/packages/web-components/fast-ssr/src/element-renderer/elemenent-renderer.spec.ts +++ b/packages/web-components/fast-ssr/src/element-renderer/elemenent-renderer.spec.ts @@ -41,8 +41,8 @@ test.describe("FASTElementRenderer", () => { const result = consolidate(templateRenderer.render(html``, defaultRenderInfo)); expect(result).toBe(""); }); - test(`should render stylesheets as 'fast-style' elements when configured`, () => { - const { templateRenderer, defaultRenderInfo} = fastSSR({useFASTStyle: true}); + test.skip(`should render stylesheets as 'fast-style' elements when configured`, () => { + const { templateRenderer, defaultRenderInfo} = fastSSR(/* Replace w/ configuration when fast-style work is complete{useFASTStyle: true}*/); const result = consolidate(templateRenderer.render(html``, defaultRenderInfo)); expect(result).toBe(``); }); diff --git a/packages/web-components/fast-ssr/src/element-renderer/element-renderer.ts b/packages/web-components/fast-ssr/src/element-renderer/element-renderer.ts index 93998ab8fed..f5daa06570b 100644 --- a/packages/web-components/fast-ssr/src/element-renderer/element-renderer.ts +++ b/packages/web-components/fast-ssr/src/element-renderer/element-renderer.ts @@ -5,6 +5,12 @@ import { TemplateRenderer } from "../template-renderer/template-renderer.js"; import { SSRView } from "../view.js"; import { FASTSSRStyleStrategy } from "./style-strategy.js"; +/** + * An {@link @lit-labs/ssr#ElementRenderer} implementation designed to render components + * built with FAST. + * + * @beta + */ export abstract class FASTElementRenderer extends ElementRenderer { /** * The element instance represented by the {@link FASTElementRenderer}. diff --git a/packages/web-components/fast-ssr/src/exports.ts b/packages/web-components/fast-ssr/src/exports.ts index b26b62370a0..5ca3b65dde9 100644 --- a/packages/web-components/fast-ssr/src/exports.ts +++ b/packages/web-components/fast-ssr/src/exports.ts @@ -7,19 +7,14 @@ import { } from "@microsoft/fast-element"; import { FASTElementRenderer } from "./element-renderer/element-renderer.js"; import { FASTSSRStyleStrategy } from "./element-renderer/style-strategy.js"; -import { - FASTStyleStyleRenderer, - StyleElementStyleRenderer, - StyleRenderer, -} from "./styles/style-renderer.js"; +import { StyleElementStyleRenderer, StyleRenderer } from "./styles/style-renderer.js"; import { defaultViewBehaviorFactoryRenderers } from "./template-renderer/directives.js"; import { + ComponentDOMEmissionMode, TemplateRenderer, - TemplateRendererConfiguration, } from "./template-renderer/template-renderer.js"; import { SSRView } from "./view.js"; -export type Configuration = TemplateRendererConfiguration; Compiler.setDefaultStrategy( ( html: string | HTMLTemplateElement, @@ -40,8 +35,6 @@ DOM.setUpdateMode(false); /** * Factory for creating SSR rendering assets. - * @param config - FAST SSR configuration - * * @example * ```ts * import "@microsoft/install-dom-shim"; @@ -51,20 +44,18 @@ DOM.setUpdateMode(false); * * const streamableSSRResult = templateRenderer.render(html`...`, defaultRenderInfo); * ``` + * + * @beta */ -export default function ( - config?: Configuration -): { +export default function fastSSR(): { templateRenderer: TemplateRenderer; elementRenderer: typeof FASTElementRenderer; defaultRenderInfo: RenderInfo; } { - const templateRenderer = new TemplateRenderer(config); + const templateRenderer = new TemplateRenderer(); const elementRenderer = class extends FASTElementRenderer { protected templateRenderer: TemplateRenderer = templateRenderer; - protected styleRenderer: StyleRenderer = config?.useFASTStyle - ? new FASTStyleStyleRenderer() - : new StyleElementStyleRenderer(); + protected styleRenderer = new StyleElementStyleRenderer(); }; templateRenderer.withViewBehaviorFactoryRenderers( @@ -81,3 +72,10 @@ export default function ( }, }; } + +export type { + TemplateRenderer, + FASTElementRenderer, + StyleRenderer, + ComponentDOMEmissionMode, +}; diff --git a/packages/web-components/fast-ssr/src/styles/style-renderer.ts b/packages/web-components/fast-ssr/src/styles/style-renderer.ts index 26e90004fd7..1e04ac28efa 100644 --- a/packages/web-components/fast-ssr/src/styles/style-renderer.ts +++ b/packages/web-components/fast-ssr/src/styles/style-renderer.ts @@ -1,4 +1,4 @@ -import { ComposableStyles, ElementStyles } from "@microsoft/fast-element"; +import { ComposableStyles } from "@microsoft/fast-element"; import { fastStyleTagName } from "./fast-style.js"; function collectStyles(style: ComposableStyles): string { let content: string = ""; @@ -19,7 +19,15 @@ function collectStyles(style: ComposableStyles): string { return content; } +/** + * A renderer for {@link @microsoft/fast-element#ComposableStyles} + * @beta + */ export interface StyleRenderer { + /** + * Renders composable styles to a string. + * @param styles - The styles to render. + */ render(styles: ComposableStyles): string; } diff --git a/packages/web-components/fast-ssr/src/template-renderer/template-renderer.spec.ts b/packages/web-components/fast-ssr/src/template-renderer/template-renderer.spec.ts index f9a3f99c2fd..cb2f75c1671 100644 --- a/packages/web-components/fast-ssr/src/template-renderer/template-renderer.spec.ts +++ b/packages/web-components/fast-ssr/src/template-renderer/template-renderer.spec.ts @@ -23,10 +23,10 @@ test.describe("TemplateRenderer", () => { }); }); - test.describe("should allow configuration", () => { + test.describe.skip("should allow configuration", () => { test("that emits to light DOM", () => { - const instance = new TemplateRenderer({componentDOMEmissionMode: "light"}); - expect(instance.componentDOMEmissionMode).toBe("light") + const instance = new TemplateRenderer(/* Re-implement w/ light mode emission is finished {componentDOMEmissionMode: "light"} */); + expect(instance.componentDOMEmissionMode).toBe("light"); }); }); diff --git a/packages/web-components/fast-ssr/src/template-renderer/template-renderer.ts b/packages/web-components/fast-ssr/src/template-renderer/template-renderer.ts index 83633ed9e7a..5836c95658d 100644 --- a/packages/web-components/fast-ssr/src/template-renderer/template-renderer.ts +++ b/packages/web-components/fast-ssr/src/template-renderer/template-renderer.ts @@ -18,44 +18,32 @@ function getLast(arr: T[]): T | undefined { return arr[arr.length - 1]; } -export type ComponentDOMEmissionMode = "shadow" | "light"; -export interface TemplateRendererConfiguration { - /** - * Controls whether the template renderer should emit component template code to the component's shadow DOM or to its light DOM. - * @default "shadow" - */ - componentDOMEmissionMode?: ComponentDOMEmissionMode; - - /** - * Controls whether the template renderer should emit FASTStyle elements for stylesheets. - * Using FASTStyle can help reduce the SSR payload by only emitting stylesheet content once, - * and leveraging a Custom Element to map those stylesheets back to FAST element's on the client. - * @default false - */ - useFASTStyle?: boolean; -} - -export class TemplateRenderer - implements Readonly> { +/** + * The mode for which a component's internals should be rendered. + * @beta + */ +export type ComponentDOMEmissionMode = "shadow"; + +/** + * A class designed to render HTML templates. The renderer supports + * rendering {@link @microsoft/fast-element#ViewTemplate} instances as well + * as arbitrary HTML strings. + * + * @beta + */ +export class TemplateRenderer { private viewBehaviorFactoryRenderers: Map< any, ViewBehaviorFactoryRenderer > = new Map(); + /** - * {@inheritDoc TemplateRendererConfiguration.componentDOMEmissionMode} + * Controls how the {@link TemplateRenderer} will emit component DOM internals. */ public readonly componentDOMEmissionMode: ComponentDOMEmissionMode = "shadow"; - /** {@inheritdoc TemplateRendererConfiguration.useFASTStyle} */ - public readonly useFASTStyle: boolean = false; - constructor(config?: TemplateRendererConfiguration) { - if (config) { - Object.assign(this, config); - } - } - /** - * + * Renders a {@link @microsoft/fast-element#ViewTemplate} or HTML string. * @param template - The template to render. * @param renderInfo - Information about the rendering context. * @param source - Any source data to render the template and evaluate bindings with. @@ -76,10 +64,11 @@ export class TemplateRenderer /** * Render a set of op codes. + * @param codes - the op codes to render. + * @param renderInfo - renderInfo context. + * @param source - source data. + * * @internal - * @param codes - * @param renderInfo - * @param source */ public *renderOpCodes( codes: Op[], @@ -95,10 +84,15 @@ export class TemplateRenderer case OpType.viewBehaviorFactory: { const factory = code.factory as ViewBehaviorFactory & Aspected; const ctor = factory.constructor; - if (this.viewBehaviorFactoryRenderers.has(ctor)) { - yield* this.viewBehaviorFactoryRenderers - .get(ctor)! - .render(factory, renderInfo, source, this, context); + const renderer = this.viewBehaviorFactoryRenderers.get(ctor); + if (renderer) { + yield* renderer.render( + factory, + renderInfo, + source, + this, + context + ); } else if (factory.aspectType && factory.binding) { const result = factory.binding(source, context); @@ -231,6 +225,8 @@ export class TemplateRenderer /** * Registers DirectiveRenderers to use when rendering templates. * @param renderers - The directive renderers to register + * + * @internal */ public withViewBehaviorFactoryRenderers( ...renderers: ViewBehaviorFactoryRenderer[] @@ -254,8 +250,8 @@ export class TemplateRenderer /** * Format attribute key/value pair into a HTML attribute string. - * @param name - * @param value + * @param name - the attribute name. + * @param value - the attribute value. */ private static formatAttribute(name: string, value: string) { return value === "" ? name : `${name}="${value}"`;