Skip to content

Commit

Permalink
feat: adds FASTElementRenderer to fast-ssr (#5613)
Browse files Browse the repository at this point in the history
* adds FASTElementRenderer as a ElementRenderer implementation

* adding test

* adding eslint for file extensions

* re-structure tests to better support dependency structures

* Fixing tests for FASTElementRenderer.matchesClass

* adding code comments

* Update packages/web-components/fast-ssr/src/element-renderer/element-renderer.ts

Co-authored-by: Jane Chu <[email protected]>

Co-authored-by: nicholasrice <[email protected]>
Co-authored-by: Jane Chu <[email protected]>
  • Loading branch information
3 people authored Feb 17, 2022
1 parent e097a1f commit 9ff9657
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 34 deletions.
6 changes: 6 additions & 0 deletions packages/web-components/fast-ssr/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: ["@microsoft/eslint-config-fast-dna", "prettier"],
rules: {
"import/extensions": ["error", "always"],
},
};
9 changes: 6 additions & 3 deletions packages/web-components/fast-ssr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@
"scripts": {
"build": "tsc -b --clean src && tsc -b src",
"build-server": "tsc -b server",
"pretest": "npm run build-server",
"test": "playwright test -c test",
"eslint": "eslint . --ext .ts",
"eslint:fix": "eslint . --ext .ts --fix",
"pretest": "npm run build-server && npm run build",
"test": "playwright test --config=playwright.config.cjs",
"test-server": "node server/dist/server.js",
"install-playwright-browsers": "npx playwright install"
},
"description": "A package for rendering FAST components outside the browser.",
"main": "index.js",
"main": "./dist/esm/index.js",
"types": "./dist/dts/index.d.ts",
"private": true,
"dependencies": {
"@lit-labs/ssr": "^1.0.0-rc.2",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// playwright.config.ts
import { PlaywrightTestConfig } from "@playwright/test";
const config: PlaywrightTestConfig = {
module.exports = {
testDir: "./dist/esm",
webServer: {
command: "npm run test-server",
port: 8080,
timeout: 120 * 1000,
reuseExistingServer: false,
},
};
export default config;
2 changes: 1 addition & 1 deletion packages/web-components/fast-ssr/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function handleStyleRequest(req: Request, res: Response) {
function handleStyleScriptRequest(req: Request, res: Response) {
res.set("Content-Type", "application/javascript");
fs.readFile(
path.resolve(__dirname, "./dist/fast-style/index.js"),
path.resolve(__dirname, "./dist/esm/fast-style/index.js"),
{ encoding: "utf8" },
(err, data) => {
const stream = (Readable as any).from(data);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import "@lit-labs/ssr/lib/install-global-dom-shim.js";
import { FASTElement } from "@microsoft/fast-element";
import { expect, test } from '@playwright/test';
import { FASTElementRenderer } from "./element-renderer.js";

test.describe("FASTElementRenderer", () => {
test.describe("should have a 'matchesClass' method", () => {
test("that returns true when invoked with a class that extends FASTElement ", () => {
class MyElement extends FASTElement {}
expect(FASTElementRenderer.matchesClass(MyElement)).toBe(true);
});
test("that returns false when invoked with a class that does not extend FASTElement ", () => {
class MyElement extends HTMLElement {}
expect(FASTElementRenderer.matchesClass(MyElement)).toBe(false);
});
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { ElementRenderer, RenderInfo } from "@lit-labs/ssr";
import { FASTElement } from "@microsoft/fast-element";

export class FASTElementRenderer extends ElementRenderer {
/**
* The element instance represented by the {@link FASTElementRenderer}.
*/
public readonly element!: FASTElement;

/**
* Tests a constructor to determine if it should be managed by a {@link FASTElementRenderer}.
* @param ctor - The constructor to test.
*/
public static matchesClass(ctor: typeof HTMLElement): boolean {
return ctor.prototype instanceof FASTElement;
}

/**
* Indicate to the {@link FASTElementRenderer} that the instance should execute DOM connection behavior.
*/
public connectedCallback(): void {
this.element.connectedCallback();
}

/**
* Constructs a new {@link FASTElementRenderer}.
* @param tagName - the tag-name of the element to create.
*/
constructor(tagName: string) {
super(tagName);

const ctor: typeof FASTElement | null = customElements.get(this.tagName);

if (ctor) {
this.element = new ctor();
} else {
throw new Error(
`FASTElementRenderer was unable to find a constructor for a custom element with the tag name '${tagName}'.`
);
}
}

/**
* Renders the component internals to light DOM instead of shadow DOM.
* @param renderInfo - information about the current rendering context.
*/
*renderLight(renderInfo: RenderInfo): IterableIterator<string> {
// TODO - this will yield out the element's template using the template renderer, skipping any shadow-DOM specific emission.
yield "";
}

/**
* Render the component internals to shadow DOM.
* @param renderInfo - information about the current rendering context.
*/
*renderShadow(renderInfo: RenderInfo): IterableIterator<string> {
// TODO - this will yield out the element's template using the template renderer
yield "";
}

/**
* Indicate to the {@link FASTElementRenderer} that an attribute has been changed.
* @param name - The name of the changed attribute
* @param old - The old attribute value
* @param value - The new attribute value
*/
attributeChangedCallback(
name: string,
old: string | null,
value: string | null
): void {
this.element.attributeChangedCallback(name, old, value);
}
}
2 changes: 1 addition & 1 deletion packages/web-components/fast-ssr/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export default "fast-ssr";
export { FASTElementRenderer } from "./element-renderer/element-renderer.js";
3 changes: 2 additions & 1 deletion packages/web-components/fast-ssr/src/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"compilerOptions": {
"composite": true,
"rootDir": ".",
"outDir": "../dist",
"outDir": "../dist/esm",
"declarationDir": "../dist/dts",
"lib": [
"dom",
"esnext"
Expand Down
10 changes: 0 additions & 10 deletions packages/web-components/fast-ssr/test/example.spec.ts

This file was deleted.

5 changes: 0 additions & 5 deletions packages/web-components/fast-ssr/test/package.json

This file was deleted.

9 changes: 0 additions & 9 deletions packages/web-components/fast-ssr/test/tsconfig.json

This file was deleted.

1 change: 1 addition & 0 deletions packages/web-components/fast-ssr/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"emitDecoratorMetadata": true,
"noEmitOnError": true,
"strict": true,
"skipLibCheck": true,
"lib": [
"dom",
"esnext"
Expand Down

0 comments on commit 9ff9657

Please sign in to comment.