wc-compiler 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -86,6 +86,6 @@ See our [website](https://merry-caramel-524e61.netlify.app/) for API docs and ex
86
86
 
87
87
  ## Motivation
88
88
 
89
- **WCC** is not a static site generator, framework or bundler. It is focused on producing raw HTML from Web Components with the intent of being easily integrated into a site generator or framework, like [**Greenwood**](https://github.com/ProjectEvergreen/greenwood/), the original motivation for creating [this project](https://github.com/ProjectEvergreen/greenwood/issues/935).
89
+ **WCC** is not a static site generator, framework or bundler. It is focused on producing raw HTML from Web Components with the intent of being easily integrated into a site generator or framework, like [**Greenwood**](https://github.com/ProjectEvergreen/greenwood/) or [**Eleventy**](https://github.com/ProjectEvergreen/eleventy-plugin-wcc/), the original motivation for creating [this project](https://github.com/ProjectEvergreen/greenwood/issues/935).
90
90
 
91
- In addition, **WCC** hopes to provide a surface area to explore patterns around [streaming](https://github.com/ProjectEvergreen/wcc/issues/5) and serverless rendering, as well as acting as a test bed for the [Web Components Community Groups](https://github.com/webcomponents-cg) discussions around community protocols, like [hydration](https://github.com/ProjectEvergreen/wcc/issues/3).
91
+ In addition, **WCC** hopes to provide a surface area to explore patterns around [streaming](https://github.com/ProjectEvergreen/wcc/issues/5) and serverless rendering, as well as acting as a test bed for the [Web Components Community Groups](https://github.com/webcomponents-cg) discussions around community protocols, like [hydration](https://github.com/ProjectEvergreen/wcc/issues/3).
package/dist/wcc.dist.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var fs = require('fs/promises');
5
+ var fs = require('fs');
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
@@ -13957,8 +13957,6 @@ var serialize = function(node, options) {
13957
13957
 
13958
13958
  // this must come first
13959
13959
 
13960
- let definitions;
13961
-
13962
13960
  function getParse(html) {
13963
13961
  return html.indexOf('<html>') >= 0 || html.indexOf('<body>') >= 0 || html.indexOf('<head>') >= 0
13964
13962
  ? parse
@@ -13973,53 +13971,58 @@ function isCustomElementDefinitionNode(node) {
13973
13971
  && expression.callee.property.name === 'define';
13974
13972
  }
13975
13973
 
13976
- async function renderComponentRoots(tree) {
13974
+ async function renderComponentRoots(tree, definitions) {
13977
13975
  for (const node of tree.childNodes) {
13978
13976
  if (node.tagName && node.tagName.indexOf('-') > 0) {
13979
13977
  const { tagName } = node;
13980
- const { moduleURL } = definitions[tagName];
13981
- const elementInstance = await initializeCustomElement(moduleURL, tagName, node.attrs);
13982
- const elementHtml = elementInstance.shadowRoot
13983
- ? elementInstance.getInnerHTML({ includeShadowRoots: true })
13984
- : elementInstance.innerHTML;
13985
- const elementTree = parseFragment(elementHtml);
13986
13978
 
13987
- node.childNodes = node.childNodes.length === 0
13988
- ? elementTree.childNodes
13989
- : [...elementTree.childNodes, ...node.childNodes];
13979
+ if (definitions[tagName]) {
13980
+ const { moduleURL } = definitions[tagName];
13981
+ const elementInstance = await initializeCustomElement(moduleURL, tagName, node.attrs, definitions);
13982
+ const elementHtml = elementInstance.shadowRoot
13983
+ ? elementInstance.getInnerHTML({ includeShadowRoots: true })
13984
+ : elementInstance.innerHTML;
13985
+ const elementTree = parseFragment(elementHtml);
13986
+
13987
+ node.childNodes = node.childNodes.length === 0
13988
+ ? elementTree.childNodes
13989
+ : [...elementTree.childNodes, ...node.childNodes];
13990
+ } else {
13991
+ console.warn(`WARNING: customElement <${tagName}> is not defined. You may not have imported it yet.`);
13992
+ }
13990
13993
  }
13991
13994
 
13992
13995
  if (node.childNodes && node.childNodes.length > 0) {
13993
- await renderComponentRoots(node);
13996
+ await renderComponentRoots(node, definitions);
13994
13997
  }
13995
13998
 
13996
13999
  // does this only apply to `<template>` tags?
13997
14000
  if (node.content && node.content.childNodes && node.content.childNodes.length > 0) {
13998
- await renderComponentRoots(node.content);
14001
+ await renderComponentRoots(node.content, definitions);
13999
14002
  }
14000
14003
  }
14001
14004
 
14002
14005
  return tree;
14003
14006
  }
14004
14007
 
14005
- async function registerDependencies(moduleURL) {
14006
- const moduleContents = await fs__default["default"].readFile(moduleURL, 'utf-8');
14008
+ function registerDependencies(moduleURL, definitions) {
14009
+ const moduleContents = fs__default["default"].readFileSync(moduleURL, 'utf-8');
14007
14010
 
14008
14011
  simple(parse$1(moduleContents, {
14009
14012
  ecmaVersion: 'latest',
14010
14013
  sourceType: 'module'
14011
14014
  }), {
14012
- async ImportDeclaration(node) {
14015
+ ImportDeclaration(node) {
14013
14016
  const specifier = node.source.value;
14014
14017
  const isBareSpecifier = specifier.indexOf('.') !== 0 && specifier.indexOf('/') !== 0;
14015
14018
 
14016
14019
  if (!isBareSpecifier) {
14017
14020
  const dependencyModuleURL = new URL(node.source.value, moduleURL);
14018
14021
 
14019
- await registerDependencies(dependencyModuleURL);
14022
+ registerDependencies(dependencyModuleURL, definitions);
14020
14023
  }
14021
14024
  },
14022
- async ExpressionStatement(node) {
14025
+ ExpressionStatement(node) {
14023
14026
  if (isCustomElementDefinitionNode(node)) {
14024
14027
  const { arguments: args } = node.expression;
14025
14028
  const tagName = args[0].value;
@@ -14034,14 +14037,14 @@ async function registerDependencies(moduleURL) {
14034
14037
  }
14035
14038
 
14036
14039
  async function getTagName(moduleURL) {
14037
- const moduleContents = await fs__default["default"].readFile(moduleURL, 'utf-8');
14040
+ const moduleContents = await fs__default["default"].promises.readFile(moduleURL, 'utf-8');
14038
14041
  let tagName;
14039
14042
 
14040
14043
  simple(parse$1(moduleContents, {
14041
14044
  ecmaVersion: 'latest',
14042
14045
  sourceType: 'module'
14043
14046
  }), {
14044
- async ExpressionStatement(node) {
14047
+ ExpressionStatement(node) {
14045
14048
  if (isCustomElementDefinitionNode(node)) {
14046
14049
 
14047
14050
  tagName = node.expression.arguments[0].value;
@@ -14052,8 +14055,8 @@ async function getTagName(moduleURL) {
14052
14055
  return tagName;
14053
14056
  }
14054
14057
 
14055
- async function initializeCustomElement(elementURL, tagName, attrs = []) {
14056
- await registerDependencies(elementURL);
14058
+ async function initializeCustomElement(elementURL, tagName, attrs = [], definitions = []) {
14059
+ registerDependencies(elementURL, definitions);
14057
14060
 
14058
14061
  // https://github.com/ProjectEvergreen/wcc/pull/67/files#r902061804
14059
14062
  const { pathname } = elementURL;
@@ -14078,16 +14081,15 @@ async function initializeCustomElement(elementURL, tagName, attrs = []) {
14078
14081
  }
14079
14082
 
14080
14083
  async function renderToString(elementURL) {
14081
- definitions = [];
14082
-
14084
+ const definitions = [];
14083
14085
  const elementTagName = await getTagName(elementURL);
14084
- const elementInstance = await initializeCustomElement(elementURL);
14086
+ const elementInstance = await initializeCustomElement(elementURL, undefined, undefined, definitions);
14085
14087
 
14086
14088
  const elementHtml = elementInstance.shadowRoot
14087
14089
  ? elementInstance.getInnerHTML({ includeShadowRoots: true })
14088
14090
  : elementInstance.innerHTML;
14089
14091
  const elementTree = getParse(elementHtml)(elementHtml);
14090
- const finalTree = await renderComponentRoots(elementTree);
14092
+ const finalTree = await renderComponentRoots(elementTree, definitions);
14091
14093
  const html = elementTagName ? `
14092
14094
  <${elementTagName}>
14093
14095
  ${serialize(finalTree)}
@@ -14102,14 +14104,14 @@ async function renderToString(elementURL) {
14102
14104
  }
14103
14105
 
14104
14106
  async function renderFromHTML(html, elements = []) {
14105
- definitions = [];
14107
+ const definitions = [];
14106
14108
 
14107
14109
  for (const url of elements) {
14108
- await initializeCustomElement(url);
14110
+ await initializeCustomElement(url, undefined, undefined, definitions);
14109
14111
  }
14110
14112
 
14111
14113
  const elementTree = getParse(html)(html);
14112
- const finalTree = await renderComponentRoots(elementTree);
14114
+ const finalTree = await renderComponentRoots(elementTree, definitions);
14113
14115
 
14114
14116
  return {
14115
14117
  html: serialize(finalTree),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wc-compiler",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "Experimental native Web Components compiler.",
5
5
  "main": "src/wcc.js",
6
6
  "type": "module",
@@ -22,8 +22,6 @@
22
22
  "develop": "concurrently \"nodemon --watch src --watch docs -e js,md,css,html ./build.js\" \"http-server ./dist --open\"",
23
23
  "build": "node ./build.js",
24
24
  "serve": "node ./build.js && http-server ./dist --open",
25
- "example:ssg": "node ./examples/ssg.js",
26
- "example:ssr": "node ./examples/ssr.js",
27
25
  "start": "npm run develop",
28
26
  "test": "c8 mocha --parallel",
29
27
  "test:tdd": "npm run test --watch",
@@ -46,6 +44,7 @@
46
44
  "http-server": "^14.1.0",
47
45
  "jsdom": "^19.0.0",
48
46
  "mocha": "^9.2.2",
47
+ "node-fetch": "^3.2.6",
49
48
  "nodemon": "^2.0.15",
50
49
  "prismjs": "^1.28.0",
51
50
  "rehype-autolink-headings": "^6.1.1",
package/src/wcc.js CHANGED
@@ -4,9 +4,7 @@ import './dom-shim.js';
4
4
  import * as acorn from 'acorn';
5
5
  import * as walk from 'acorn-walk';
6
6
  import { parse, parseFragment, serialize } from 'parse5';
7
- import fs from 'fs/promises';
8
-
9
- let definitions;
7
+ import fs from 'fs';
10
8
 
11
9
  function getParse(html) {
12
10
  return html.indexOf('<html>') >= 0 || html.indexOf('<body>') >= 0 || html.indexOf('<head>') >= 0
@@ -22,53 +20,58 @@ function isCustomElementDefinitionNode(node) {
22
20
  && expression.callee.property.name === 'define';
23
21
  }
24
22
 
25
- async function renderComponentRoots(tree) {
23
+ async function renderComponentRoots(tree, definitions) {
26
24
  for (const node of tree.childNodes) {
27
25
  if (node.tagName && node.tagName.indexOf('-') > 0) {
28
26
  const { tagName } = node;
29
- const { moduleURL } = definitions[tagName];
30
- const elementInstance = await initializeCustomElement(moduleURL, tagName, node.attrs);
31
- const elementHtml = elementInstance.shadowRoot
32
- ? elementInstance.getInnerHTML({ includeShadowRoots: true })
33
- : elementInstance.innerHTML;
34
- const elementTree = parseFragment(elementHtml);
35
-
36
- node.childNodes = node.childNodes.length === 0
37
- ? elementTree.childNodes
38
- : [...elementTree.childNodes, ...node.childNodes];
27
+
28
+ if (definitions[tagName]) {
29
+ const { moduleURL } = definitions[tagName];
30
+ const elementInstance = await initializeCustomElement(moduleURL, tagName, node.attrs, definitions);
31
+ const elementHtml = elementInstance.shadowRoot
32
+ ? elementInstance.getInnerHTML({ includeShadowRoots: true })
33
+ : elementInstance.innerHTML;
34
+ const elementTree = parseFragment(elementHtml);
35
+
36
+ node.childNodes = node.childNodes.length === 0
37
+ ? elementTree.childNodes
38
+ : [...elementTree.childNodes, ...node.childNodes];
39
+ } else {
40
+ console.warn(`WARNING: customElement <${tagName}> is not defined. You may not have imported it yet.`);
41
+ }
39
42
  }
40
43
 
41
44
  if (node.childNodes && node.childNodes.length > 0) {
42
- await renderComponentRoots(node);
45
+ await renderComponentRoots(node, definitions);
43
46
  }
44
47
 
45
48
  // does this only apply to `<template>` tags?
46
49
  if (node.content && node.content.childNodes && node.content.childNodes.length > 0) {
47
- await renderComponentRoots(node.content);
50
+ await renderComponentRoots(node.content, definitions);
48
51
  }
49
52
  }
50
53
 
51
54
  return tree;
52
55
  }
53
56
 
54
- async function registerDependencies(moduleURL) {
55
- const moduleContents = await fs.readFile(moduleURL, 'utf-8');
57
+ function registerDependencies(moduleURL, definitions) {
58
+ const moduleContents = fs.readFileSync(moduleURL, 'utf-8');
56
59
 
57
60
  walk.simple(acorn.parse(moduleContents, {
58
61
  ecmaVersion: 'latest',
59
62
  sourceType: 'module'
60
63
  }), {
61
- async ImportDeclaration(node) {
64
+ ImportDeclaration(node) {
62
65
  const specifier = node.source.value;
63
66
  const isBareSpecifier = specifier.indexOf('.') !== 0 && specifier.indexOf('/') !== 0;
64
67
 
65
68
  if (!isBareSpecifier) {
66
69
  const dependencyModuleURL = new URL(node.source.value, moduleURL);
67
70
 
68
- await registerDependencies(dependencyModuleURL);
71
+ registerDependencies(dependencyModuleURL, definitions);
69
72
  }
70
73
  },
71
- async ExpressionStatement(node) {
74
+ ExpressionStatement(node) {
72
75
  if (isCustomElementDefinitionNode(node)) {
73
76
  const { arguments: args } = node.expression;
74
77
  const tagName = args[0].value;
@@ -83,14 +86,14 @@ async function registerDependencies(moduleURL) {
83
86
  }
84
87
 
85
88
  async function getTagName(moduleURL) {
86
- const moduleContents = await fs.readFile(moduleURL, 'utf-8');
89
+ const moduleContents = await fs.promises.readFile(moduleURL, 'utf-8');
87
90
  let tagName;
88
91
 
89
92
  walk.simple(acorn.parse(moduleContents, {
90
93
  ecmaVersion: 'latest',
91
94
  sourceType: 'module'
92
95
  }), {
93
- async ExpressionStatement(node) {
96
+ ExpressionStatement(node) {
94
97
  if (isCustomElementDefinitionNode(node)) {
95
98
 
96
99
  tagName = node.expression.arguments[0].value;
@@ -101,8 +104,8 @@ async function getTagName(moduleURL) {
101
104
  return tagName;
102
105
  }
103
106
 
104
- async function initializeCustomElement(elementURL, tagName, attrs = []) {
105
- await registerDependencies(elementURL);
107
+ async function initializeCustomElement(elementURL, tagName, attrs = [], definitions = []) {
108
+ registerDependencies(elementURL, definitions);
106
109
 
107
110
  // https://github.com/ProjectEvergreen/wcc/pull/67/files#r902061804
108
111
  const { pathname } = elementURL;
@@ -127,16 +130,15 @@ async function initializeCustomElement(elementURL, tagName, attrs = []) {
127
130
  }
128
131
 
129
132
  async function renderToString(elementURL) {
130
- definitions = [];
131
-
133
+ const definitions = [];
132
134
  const elementTagName = await getTagName(elementURL);
133
- const elementInstance = await initializeCustomElement(elementURL);
135
+ const elementInstance = await initializeCustomElement(elementURL, undefined, undefined, definitions);
134
136
 
135
137
  const elementHtml = elementInstance.shadowRoot
136
138
  ? elementInstance.getInnerHTML({ includeShadowRoots: true })
137
139
  : elementInstance.innerHTML;
138
140
  const elementTree = getParse(elementHtml)(elementHtml);
139
- const finalTree = await renderComponentRoots(elementTree);
141
+ const finalTree = await renderComponentRoots(elementTree, definitions);
140
142
  const html = elementTagName ? `
141
143
  <${elementTagName}>
142
144
  ${serialize(finalTree)}
@@ -151,14 +153,14 @@ async function renderToString(elementURL) {
151
153
  }
152
154
 
153
155
  async function renderFromHTML(html, elements = []) {
154
- definitions = [];
156
+ const definitions = [];
155
157
 
156
158
  for (const url of elements) {
157
- await initializeCustomElement(url);
159
+ await initializeCustomElement(url, undefined, undefined, definitions);
158
160
  }
159
161
 
160
162
  const elementTree = getParse(html)(html);
161
- const finalTree = await renderComponentRoots(elementTree);
163
+ const finalTree = await renderComponentRoots(elementTree, definitions);
162
164
 
163
165
  return {
164
166
  html: serialize(finalTree),