Skip to content

Commit

Permalink
initial pass of adding JSDocs and tsc for CI
Browse files Browse the repository at this point in the history
  • Loading branch information
thescientist13 committed Feb 20, 2025
1 parent 20fd88b commit ec5713e
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ jobs:
- name: Lint
run: |
npm run lint
- name: Check Types
run: |
npm run lint:types
- name: Test
run: |
npm test
Expand Down
68 changes: 66 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"scripts": {
"clean": "rimraf ./dist",
"lint": "eslint",
"lint:types": "tsc --project tsconfig.json",
"docs:dev": "concurrently \"nodemon --watch src --watch docs -e js,md,css,html,jsx ./build.js\" \"http-server ./dist --open\"",
"docs:build": "node ./build.js",
"docs:serve": "npm run clean && npm run docs:build && http-server ./dist --open",
Expand Down Expand Up @@ -58,6 +59,8 @@
"@mapbox/rehype-prism": "^0.8.0",
"@rollup/plugin-commonjs": "^28.0.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@types/mocha": "^10.0.10",
"@types/node": "^22.13.4",
"c8": "^7.11.2",
"chai": "^4.3.6",
"concurrently": "^7.1.0",
Expand All @@ -80,6 +83,7 @@
"rimraf": "^3.0.2",
"rollup": "^4.26.0",
"simple.css": "^0.1.3",
"typescript": "^5.7.3",
"unified": "^10.1.2"
}
}
1 change: 1 addition & 0 deletions src/dom-shim.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-nocheck
import { parse, parseFragment, serialize } from 'parse5';

export function getParse(html) {
Expand Down
11 changes: 11 additions & 0 deletions src/jsx-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { generate } from 'astring';
import fs from 'fs';
// ideally we can eventually adopt an ESM compatible version of this plugin
// https://github.com/acornjs/acorn-jsx/issues/112
// @ts-ignore
// but it does have a default export???
import jsx from '@projectevergreen/acorn-jsx-esm';
import { parse, parseFragment, serialize } from 'parse5';
import { transform } from 'sucrase';
Expand Down Expand Up @@ -250,11 +252,13 @@ export function parseJsx(moduleURL) {

walk.simple(tree, {
ClassDeclaration(node) {
// @ts-ignore
if (node.superClass.name === 'HTMLElement') {
const hasShadowRoot = moduleContents.slice(node.body.start, node.body.end).indexOf('this.attachShadow(') > 0;

for (const n1 of node.body.body) {
if (n1.type === 'MethodDefinition') {
// @ts-ignore
const nodeName = n1.key.name;
if (nodeName === 'render') {
for (const n2 in n1.value.body.body) {
Expand All @@ -265,6 +269,7 @@ export function parseJsx(moduleURL) {
...observedAttributes,
...findThisReferences('render', n)
];
// @ts-ignore
} else if (n.type === 'ReturnStatement' && n.argument.type === 'JSXElement') {
const html = parseJsxElement(n.argument, moduleContents);
const elementTree = getParse(html)(html);
Expand Down Expand Up @@ -296,6 +301,7 @@ export function parseJsx(moduleURL) {
sourceType: 'module'
});

// @ts-ignore
n1.value.body.body[n2] = transformed;
}
}
Expand All @@ -308,14 +314,17 @@ export function parseJsx(moduleURL) {
const { declaration } = node;

if (declaration && declaration.type === 'VariableDeclaration' && declaration.kind === 'const' && declaration.declarations.length === 1) {
// @ts-ignore
if (declaration.declarations[0].id.name === 'inferredObservability') {
// @ts-ignore
inferredObservability = Boolean(node.declaration.declarations[0].init.raw);
}
}
}
}, {
// https://github.com/acornjs/acorn/issues/829#issuecomment-1172586171
...walk.base,
// @ts-ignore
JSXElement: () => {}
});

Expand All @@ -324,7 +333,9 @@ export function parseJsx(moduleURL) {
let insertPoint;
for (const line of tree.body) {
// test for class MyComponent vs export default class MyComponent
// @ts-ignore
if (line.type === 'ClassDeclaration' || (line.declaration && line.declaration.type) === 'ClassDeclaration') {
// @ts-ignore
insertPoint = line.declaration.body.start + 1;
}
}
Expand Down
32 changes: 25 additions & 7 deletions src/wcc.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,23 @@ function registerDependencies(moduleURL, definitions, depth = 0) {
}), {
ImportDeclaration(node) {
const specifier = node.source.value;
const isBareSpecifier = specifier.indexOf('.') !== 0 && specifier.indexOf('/') !== 0;
const extension = specifier.split('.').pop();

// would like to decouple .jsx from the core, ideally
// https://github.com/ProjectEvergreen/wcc/issues/122
if (!isBareSpecifier && ['js', 'jsx', 'ts'].includes(extension)) {
const dependencyModuleURL = new URL(node.source.value, moduleURL);
if (typeof specifier === 'string') {
const isBareSpecifier = specifier.indexOf('.') !== 0 && specifier.indexOf('/') !== 0;
const extension = typeof specifier === "string" ? specifier.split('.').pop() : "";

registerDependencies(dependencyModuleURL, definitions, nextDepth);
// would like to decouple .jsx from the core, ideally
// https://github.com/ProjectEvergreen/wcc/issues/122
if (!isBareSpecifier && ['js', 'jsx', 'ts'].includes(extension)) {
const dependencyModuleURL = new URL(specifier, moduleURL);

registerDependencies(dependencyModuleURL, definitions, nextDepth);
}
}
},
ExpressionStatement(node) {
if (isCustomElementDefinitionNode(node)) {
// @ts-ignore
const { arguments: args } = node.expression;
const tagName = args[0].type === 'Literal'
? args[0].value // single and double quotes
Expand Down Expand Up @@ -134,6 +138,7 @@ async function getTagName(moduleURL) {
}), {
ExpressionStatement(node) {
if (isCustomElementDefinitionNode(node)) {
// @ts-ignore
tagName = node.expression.arguments[0].value;
}
}
Expand Down Expand Up @@ -167,6 +172,13 @@ async function initializeCustomElement(elementURL, tagName, node = {}, definitio
}
}

/**
* @param {URL} elementURL - The entry point custom element definition
* @param {boolean} wrappingEntryTag - Whether to wrap (or not wrap) your entry point's HTML in a custom element tag
* @param {any} props - Constructor props
*
* @returns {Promise<{ html: string, metadata: any[] }>}- Fully rendered HTML contents and custom elements metadata
*/
async function renderToString(elementURL, wrappingEntryTag = true, props = {}) {
const definitions = [];
const elementTagName = wrappingEntryTag && await getTagName(elementURL);
Expand Down Expand Up @@ -207,6 +219,12 @@ async function renderToString(elementURL, wrappingEntryTag = true, props = {}) {
};
}

/**
* @param {string} html - The HTML contents to render from
* @param {URL[]} elements - Custom element definitions to pass to the renderer
*
* @returns {Promise<{ html: string, metadata: any[] }>} Fully rendered HTML contents and custom elements metadata
*/
async function renderFromHTML(html, elements = []) {
const definitions = [];

Expand Down
21 changes: 21 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "esnext",
"module": "nodenext",
"allowImportingTsExtensions": true,
"rewriteRelativeImportExtensions": true,
"verbatimModuleSyntax": true,
"checkJs": true,
"allowJs": true,
"noEmit": true,
"skipLibCheck": true,
"types": [
"mocha",
"node"
]
},
"include": [
"./src/",
"./test/**/*.spec.js"
]
}

0 comments on commit ec5713e

Please sign in to comment.