Skip to content

Commit

Permalink
adds api extractor and configures exports. Also removes entrypoints t…
Browse files Browse the repository at this point in the history
…o certain incomplete features
  • Loading branch information
nicholasrice committed May 4, 2022
1 parent 74c0c9b commit 6af46c9
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 63 deletions.
9 changes: 9 additions & 0 deletions packages/web-components/fast-ssr/api-extractor.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
62 changes: 62 additions & 0 deletions packages/web-components/fast-ssr/docs/api-report.md
Original file line number Diff line number Diff line change
@@ -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<string>;
renderShadow(renderInfo: RenderInfo): IterableIterator<string>;
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<string>;
// 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<string>;
// Warning: (ae-forgotten-export) The symbol "ViewBehaviorFactoryRenderer" needs to be exported by the entry point exports.d.ts
//
// @internal
withViewBehaviorFactoryRenderers(...renderers: ViewBehaviorFactoryRenderer<any>[]): void;
}

// (No @packageDocumentation comment for this package)

```
12 changes: 9 additions & 3 deletions packages/web-components/fast-ssr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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,
Expand All @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ test.describe("FASTElementRenderer", () => {
const result = consolidate(templateRenderer.render(html`<styled-element></styled-element>`, defaultRenderInfo));
expect(result).toBe("<styled-element><template shadowroot=\"open\"><style>:host { display: block; }</style><style>:host { color: red; }</style></template></styled-element>");
});
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`<styled-element></styled-element>`, defaultRenderInfo));
expect(result).toBe(`<styled-element><template shadowroot=\"open\"><fast-style style-id="fast-style-0" css=":host { display: block; }\"></fast-style><fast-style style-id=\"fast-style-1\" css=\":host { color: red; }"></fast-style></template></styled-element>`);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}.
Expand Down
30 changes: 14 additions & 16 deletions packages/web-components/fast-ssr/src/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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";
Expand All @@ -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(
Expand All @@ -81,3 +72,10 @@ export default function (
},
};
}

export type {
TemplateRenderer,
FASTElementRenderer,
StyleRenderer,
ComponentDOMEmissionMode,
};
10 changes: 9 additions & 1 deletion packages/web-components/fast-ssr/src/styles/style-renderer.ts
Original file line number Diff line number Diff line change
@@ -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 = "";
Expand All @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,44 +18,32 @@ function getLast<T>(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<Required<TemplateRendererConfiguration>> {
/**
* 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<any>
> = 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.
Expand All @@ -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[],
Expand All @@ -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);

Expand Down Expand Up @@ -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<any>[]
Expand All @@ -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}"`;
Expand Down

0 comments on commit 6af46c9

Please sign in to comment.