@package-verse/esmpack 1.0.2 → 1.0.3

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.
@@ -32,6 +32,7 @@
32
32
  "cloner",
33
33
  "Coogan",
34
34
  "Couuntry",
35
+ "CSSJS",
35
36
  "Da'uli",
36
37
  "Daiko",
37
38
  "Darabukka",
@@ -34,15 +34,11 @@
34
34
  {
35
35
  "label": "Web Atoms Dev Server",
36
36
  "type": "shell",
37
- "command": "wads",
37
+ "command": "npm",
38
38
  "args": [
39
- // "https://v2018-beta.tas800.com",
40
- // "https://v2018.tas800.com",
41
- // "https://v2025-test.800casting.com"
42
- "https://v2025-test.tas800.com"
43
- //"http://localhost:9991"
44
- ],
45
- "problemMatcher": []
39
+ "run",
40
+ "test-server"
41
+ ]
46
42
  }
47
43
  ]
48
44
  }
package/README.md CHANGED
@@ -8,3 +8,16 @@ Because, there is no simple packer that just rewrites module paths. After ES6 an
8
8
  1. Creates a single pack JS file which only has import definition of all the imports.
9
9
  2. Packed file strips css and delivers separate css as combined CSS.
10
10
  3. Retains ESM source code as it is except import path, import path is rewritten to fully qualified CDN url. So caching is preserved over different main module versions but same dependencies.
11
+
12
+
13
+ ## Dev Packer
14
+
15
+ 1. Development time packer will generate HTML file along with the pack that will generate import maps along with the loading of control and hosting it.
16
+ 2. Dev Packer will generate `let cs = document.currentScript;import("imported-path").then((r) => ESMPack.render(r, cs))` script inside html for every JS's corresponding html.
17
+ 3. Library author must implement `ESMPack.render` method which will accept exports from imported method and `currentScript`.
18
+ 4. Every `js` file's imports will be changed to fully qualified references for external imports.
19
+
20
+ ## Release Packer
21
+
22
+ 1. A single script with `.pack.js` will be generated that will import every nested imports along with fully qualified path for every nested imported external references.
23
+ 2. Every `js` file's imports will be changed to fully qualified references for external imports.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@package-verse/esmpack",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "ESM Pack Packer and Web Server with PostCSS and ESM Loader",
5
5
  "homepage": "https://github.com/package-verse/esmpack#readme",
6
6
  "bugs": {
@@ -16,9 +16,29 @@
16
16
  "scripts": {
17
17
  "test": "exit 0",
18
18
  "push": "git add -A && git commit -m \"dep vb\" && npm version patch",
19
+ "build-css-watch": "npx postcss \"./src/**/*.css\" --base src --dir dist --map --verbose -w",
20
+ "test-server": "node --enable-source-maps ./serve.js",
19
21
  "postversion": "git push --follow-tags"
20
22
  },
21
23
  "devDependencies": {
22
- "@types/node": "^25.5.0"
24
+ "@types/node": "^25.5.0",
25
+ "@types/ws": "^8.18.1",
26
+ "cssnano": "^7.0.6",
27
+ "postcss": "^8.5.3",
28
+ "postcss-cli": "^11.0.1",
29
+ "postcss-import": "^16.1.0",
30
+ "postcss-import-ext-glob": "^2.1.1",
31
+ "postcss-import-styled-js": "^1.0.23",
32
+ "postcss-nested": "^7.0.2",
33
+ "postcss-preset-env": "^10.1.5",
34
+ "postcss-url": "^10.1.3"
35
+ },
36
+ "dependencies": {
37
+ "@web-atoms/date-time": "^3.0.3",
38
+ "colors": "^1.4.0",
39
+ "http-proxy-middleware": "^3.0.5",
40
+ "mime": "^4.1.0",
41
+ "portfinder": "^1.0.38",
42
+ "ws": "^8.19.0"
23
43
  }
24
44
  }
@@ -0,0 +1,18 @@
1
+ module.exports = (ctx) => ({
2
+ map: { ... ctx.options.map, sourcesContent: false },
3
+ plugins: [
4
+ require("postcss-import-styled-js")(),
5
+ require('postcss-preset-env')({
6
+ stage: 4
7
+ }),
8
+ require("postcss-import-ext-glob")(),
9
+ require("postcss-import")(),
10
+ require("postcss-url")({
11
+ url: "rebase",
12
+ basePath: ctx.options.base,
13
+ assetsPath: ctx.options.dist
14
+ }),
15
+ require("postcss-nested")(),
16
+ require("cssnano")()
17
+ ]
18
+ });
package/serve.js ADDED
@@ -0,0 +1 @@
1
+ import "./dist/serve/serve.js";
@@ -0,0 +1,17 @@
1
+ export const ProcessOptions = {
2
+ cwd: ""
3
+ };
4
+
5
+ const { argv } = process;
6
+ const { length } = argv;
7
+ for(let i=0; i< length;i++) {
8
+ const arg = argv[i];
9
+ if (arg.startsWith("--")) {
10
+ ProcessOptions[arg] = argv[i+1] || void 0;
11
+ }
12
+ }
13
+
14
+ const last = argv[argv.length-1];
15
+ export const fileArgument = last.startsWith("--") ? void 0 : last;
16
+
17
+ ProcessOptions.cwd ||= process.cwd();
@@ -0,0 +1,14 @@
1
+ import { tokenizeRegexAll } from "./tokenizeAll.js";
2
+
3
+ export type regExpTokens = { text: string, match: RegExpMatchArray };
4
+
5
+ export const RegExpExtra = {
6
+
7
+ replaceAll(text: string, regExp: RegExp, transformer: (item: regExpTokens) => string) {
8
+ let r = "";
9
+ for(const token of tokenizeRegexAll(text, regExp)) {
10
+ r += transformer(token as any);
11
+ }
12
+ return r;
13
+ },
14
+ };
@@ -0,0 +1,40 @@
1
+ export function *tokenizeRegexAll(text: string, regex: RegExp) {
2
+ if (!text) {
3
+ return;
4
+ }
5
+ regex.lastIndex = 0;
6
+ let start = 0;
7
+ for(const m of text.matchAll(regex)) {
8
+ if (start < m.index) {
9
+ yield { text: text.substring(start, m.index)};
10
+ }
11
+ yield { match: m };
12
+ start = m.index + m[0].length;
13
+ }
14
+ if (start < text.length) {
15
+ if (start) {
16
+ yield { text: text.substring(start) };
17
+ } else {
18
+ yield { text };
19
+ }
20
+ }
21
+ // let m;
22
+ // let start = 0;
23
+ // while((m = regex.exec(text)) !== null) {
24
+ // const { lastIndex } = regex;
25
+ // if (m.index === lastIndex) {
26
+ // regex.lastIndex++;
27
+ // }
28
+ // if (!m?.length) {
29
+ // break;
30
+ // }
31
+ // if (start < m.index) {
32
+ // yield { text: text.substring(start, m.index)};
33
+ // }
34
+ // yield { match: m as RegExpExecArray };
35
+ // start = m.index + m[0].length;
36
+ // }
37
+ // if (start < text.length) {
38
+ // yield { text: text.substring(start) };
39
+ // }
40
+ }
@@ -0,0 +1,63 @@
1
+ import { IncomingMessage, ServerResponse } from "http";
2
+ import path from "path";
3
+ import { fileArgument, ProcessOptions } from "../ProcessArgs.js";
4
+ import { existsSync } from "fs";
5
+ import sendLocalFile from "./send/sendLocalFile.js";
6
+ import { createProxyMiddleware, fixRequestBody } from "http-proxy-middleware";
7
+ import colors from "colors";
8
+ import sendJSHost from "./send/sendJSHost.js";
9
+ import sendCSSJS from "./send/sendCSSJS.js";
10
+
11
+
12
+ let middleware;
13
+
14
+ export default function WebServer(req: IncomingMessage, res: ServerResponse) {
15
+ const pathname = new URL(req.url, "http://a").pathname.substring(1);
16
+
17
+ // check if path exists...
18
+ const fullPath = path.resolve(ProcessOptions.cwd, pathname);
19
+ if (existsSync(fullPath)) {
20
+ // server local..
21
+ sendLocalFile(pathname, fullPath, req, res);
22
+ return;
23
+ }
24
+
25
+ const css = fullPath.replace(/\.js$/, "");
26
+ if (existsSync(css)) {
27
+ sendCSSJS(pathname.substring(0, pathname.length - 3), req, res);
28
+ return;
29
+ }
30
+
31
+ const js = fullPath.replace(/\.html$/,".js");
32
+ if(existsSync(js)) {
33
+ sendJSHost(pathname.replace(/\.html$/, ".js"), req, res);
34
+ return;
35
+ }
36
+
37
+ // proxy...
38
+ middleware ??= createProxyMiddleware({
39
+ target: fileArgument,
40
+ changeOrigin: true,
41
+ ws: true,
42
+ secure: false,
43
+ cookieDomainRewrite: "",
44
+ on: {
45
+ proxyReq: fixRequestBody,
46
+ proxyRes:(proxyReq, req, res) => {
47
+ if (proxyReq.statusCode >= 400) {
48
+ console.error(colors.red(`HTTP STATUS ${proxyReq.statusCode} for ${fileArgument}${req.url}`));
49
+ } else if (proxyReq.statusCode >= 300) {
50
+ console.warn(colors.yellow(
51
+ `HTTP STATUS ${proxyReq.statusCode} for ${fileArgument}${req.url}`));
52
+ }
53
+ let cookie = proxyReq.headers["set-cookie"];
54
+ if (cookie) {
55
+ cookie = cookie.map((s) => s.split(";").filter((c) => c.trim().toLocaleLowerCase() !== "secure").join(";"));
56
+ proxyReq.headers["set-cookie"] = cookie;
57
+ }
58
+ }
59
+ }
60
+ });
61
+
62
+ middleware(req, res);
63
+ }
@@ -0,0 +1,7 @@
1
+ import { readFileSync } from "fs";
2
+ import { ProcessOptions } from "../../ProcessArgs.js";
3
+ import { join } from "path";
4
+
5
+ const jsonText = readFileSync(join(ProcessOptions.cwd, "package.json"), "utf-8");
6
+
7
+ export const packageInfo = JSON.parse(jsonText);
@@ -0,0 +1,22 @@
1
+ import { IncomingMessage, ServerResponse } from "node:http";
2
+
3
+ export default function sendCSSJS(path: string, req: IncomingMessage, res: ServerResponse) {
4
+ const text = `
5
+ (function () {
6
+
7
+ function loadCSS() {
8
+ if (typeof ESMPack === "undefined") {
9
+ setTimeout(loadCSS, 100);
10
+ return;
11
+ }
12
+ ESMPack.installStyleSheet("/${path}");
13
+ }
14
+ loadCSS();
15
+
16
+
17
+ }())
18
+ `;
19
+
20
+ res.writeHead(200, { "content-type": "text/javascript"});
21
+ res.end(text);
22
+ }
@@ -0,0 +1,52 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { IncomingMessage, ServerResponse } from "node:http";
3
+ import { RegExpExtra } from "../../core/RegExpExtra.js";
4
+
5
+ export default function sendJS(path: string, req: IncomingMessage, res: ServerResponse) {
6
+ let text = readFileSync(path, "utf-8");
7
+
8
+ // change references....
9
+ // text = text.replace(/from\s*\"([^\.][^\"]+)\"/gm, `from "/node_modules/$1"`);
10
+
11
+ // remap CSS
12
+ text = RegExpExtra.replaceAll(text, /from\s*\"([^\"]+)\"/gm, (
13
+ { text, match }
14
+ ) => {
15
+ if (text) {
16
+ return text;
17
+ }
18
+ const [matched, g] = match;
19
+ if (g.endsWith(".css")) {
20
+ // we need to find source...
21
+ return `from "/node_modules/${g}.js"`;
22
+ }
23
+ if (g.startsWith(".")) {
24
+ return matched;
25
+ }
26
+ return `from "/node_modules/${g}"`;
27
+ });
28
+
29
+ text = RegExpExtra.replaceAll(text, /import\s*\"([^\"]+)\"/gm, (
30
+ { text, match }
31
+ ) => {
32
+ if (text) {
33
+ return text;
34
+ }
35
+ const [matched, g] = match;
36
+ if (g.endsWith(".css")) {
37
+ // we need to find source...
38
+ let cssPath = g;
39
+ if (!cssPath.startsWith(".")) {
40
+ cssPath = "/node_modules/" + cssPath;
41
+ }
42
+ return `import "${cssPath}.js"`;
43
+ }
44
+ if (g.startsWith(".")) {
45
+ return matched;
46
+ }
47
+ return `import "/node_modules/${g}"`;
48
+ });
49
+
50
+ res.writeHead(200, { "content-type": "text/javascript "});
51
+ res.end(text);
52
+ }
@@ -0,0 +1,23 @@
1
+ import { IncomingMessage, ServerResponse } from "node:http";
2
+
3
+ export default function sendJSHost(path: string, req: IncomingMessage, res: ServerResponse) {
4
+ const text = `
5
+ <!DOCTYPE html>
6
+ <html lang="en">
7
+ <head>
8
+ <meta charset="UTF-8" />
9
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
10
+ <title>Index of ${path}</title>
11
+ </head>
12
+ <body>
13
+ <script>
14
+ const cs = document.currentScript;
15
+ import("/${path}").then((r) => ESMPack.render(r, cs), (error) => cs.replaceWith(document.createTextNode(error.stack || error)));
16
+ </script>
17
+ </body>
18
+ </html>
19
+ `;
20
+
21
+ res.writeHead(200, { "content-type": "text/html"});
22
+ res.end(text);
23
+ }
@@ -0,0 +1,96 @@
1
+ import { readdirSync, statSync } from "node:fs";
2
+ import { IncomingMessage, ServerResponse } from "node:http";
3
+ import { join } from "node:path";
4
+
5
+ export default function sendList(reqPath, path: string, req: IncomingMessage, res: ServerResponse) {
6
+
7
+ const entries = readdirSync(path, { withFileTypes: true})
8
+ .filter((d) => !d.name.startsWith(".") && d.name !== "node_modules")
9
+ .map((d) => {
10
+ const fullPath = join(d.parentPath, d.name);
11
+ let size = 0, mtime = new Date();
12
+ try {
13
+ const s = statSync(fullPath);
14
+ size = s.size;
15
+ mtime = s.mtime;
16
+ } catch {}
17
+ return { name: d.name, isDir: d.isDirectory(), size, mtime };
18
+ })
19
+ .sort((a, b) => {
20
+ if (a.isDir !== b.isDir) return a.isDir ? -1 : 1;
21
+ return a.name.localeCompare(b.name);
22
+ });
23
+
24
+
25
+ const text = renderDirectoryListing(reqPath, entries);
26
+
27
+ res.writeHead(200, {"Content-Type": "text/html"});
28
+ res.end(text);
29
+ }
30
+
31
+ function formatSize(bytes) {
32
+ if (bytes === 0) return "0 B";
33
+ const units = ["B", "KB", "MB", "GB"];
34
+ const i = Math.floor(Math.log(bytes) / Math.log(1024));
35
+ return `${(bytes / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 1)} ${units[i]}`;
36
+ }
37
+
38
+ function renderDirectoryListing(reqPath, entries: { isDir: boolean, name: string, size: number, mtime: Date } []) {
39
+
40
+
41
+ const isRoot = reqPath === "/";
42
+ const rows = entries
43
+ .map((e) => {
44
+ let href = reqPath.replace(/\/$/, "") + "/" + encodeURIComponent(e.name) + (e.isDir ? "/" : "");
45
+ const icon = e.isDir ? "📁" : (/\.(js|html)$/i.test(e.name) ? "🌐" : "📄");
46
+ const size = e.isDir ? "—" : formatSize(e.size);
47
+ const modified = e.mtime.toISOString().replace("T", " ").slice(0, 19);
48
+
49
+ if (e.name.endsWith(".js")) {
50
+ href = href.replace(/\.js$/, ".html");
51
+ }
52
+
53
+ return `<tr>
54
+ <td>${icon} <a href="${href.startsWith("/") ? href : "/" + href}">${e.name}${e.isDir ? "/" : ""}</a></td>
55
+ <td>${size}</td>
56
+ <td>${modified}</td>
57
+ </tr>`;
58
+ })
59
+ .join("\n");
60
+
61
+ const parentRow = isRoot
62
+ ? ""
63
+ : `<tr><td>⬆️ <a href="../">../</a></td><td>—</td><td>—</td></tr>`;
64
+
65
+ return `<!DOCTYPE html>
66
+ <html lang="en">
67
+ <head>
68
+ <meta charset="UTF-8" />
69
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
70
+ <title>Index of ${reqPath}</title>
71
+ <style>
72
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
73
+ body { font-family: ui-monospace, 'Cascadia Code', monospace; background: #0f1117; color: #e2e8f0; min-height: 100vh; padding: 2rem; }
74
+ h1 { font-size: 1.25rem; color: #7dd3fc; margin-bottom: 1.5rem; border-bottom: 1px solid #1e293b; padding-bottom: .75rem; }
75
+ table { width: 100%; border-collapse: collapse; }
76
+ th { text-align: left; padding: .5rem .75rem; color: #94a3b8; font-weight: 600; font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; border-bottom: 1px solid #1e293b; }
77
+ td { padding: .45rem .75rem; font-size: .9rem; border-bottom: 1px solid #0d1520; }
78
+ td:nth-child(2), td:nth-child(3) { color: #64748b; font-size: .8rem; white-space: nowrap; }
79
+ tr:hover td { background: #1e293b; }
80
+ a { color: #7dd3fc; text-decoration: none; }
81
+ a:hover { color: #bae6fd; text-decoration: underline; }
82
+ footer { margin-top: 2rem; color: #334155; font-size: .75rem; }
83
+ </style>
84
+ </head>
85
+ <body>
86
+ <h1>📂 Index of ${reqPath}</h1>
87
+ <table>
88
+ <thead><tr><th>Name</th><th>Size</th><th>Modified</th></tr></thead>
89
+ <tbody>
90
+ ${parentRow}
91
+ ${rows}
92
+ </tbody>
93
+ </table>
94
+ </body>
95
+ </html>`;
96
+ }
@@ -0,0 +1,33 @@
1
+ import { createReadStream, statSync } from "node:fs";
2
+ import { IncomingMessage, ServerResponse } from "node:http";
3
+ import mime from "mime";
4
+ import sendList from "./sendList.js";
5
+ import sendJS from "./sendJS.js";
6
+ export default function sendLocalFile(reqPath: string, path: string, req: IncomingMessage, res: ServerResponse) {
7
+
8
+ if (path.endsWith(".js")) {
9
+ // send JS
10
+ return sendJS(path, req, res);
11
+ }
12
+
13
+ // check if it is a folder...
14
+ const stat = statSync(path);
15
+ if (stat.isDirectory()) {
16
+ // list...
17
+ return sendList(reqPath, path, req, res);
18
+ }
19
+ // just pipe the file...
20
+ sendFile(path, res);
21
+ }
22
+
23
+ function sendFile(filePath, res) {
24
+ const stream = createReadStream(filePath);
25
+ stream.on("error", (err) => {
26
+ if (!res.headersSent) {
27
+ res.writeHead(500, { "Content-Type": "text/plain" });
28
+ res.end(`500 Internal Server Error\n\n${err.message}`);
29
+ }
30
+ });
31
+ res.writeHead(200, { "Content-Type": mime.getType(filePath) });
32
+ stream.pipe(res);
33
+ }
@@ -0,0 +1,146 @@
1
+ import app from "./WebServer.js";
2
+ import portfinder from "portfinder";
3
+ import os from "os";
4
+ import colors from "colors";
5
+ import http from "http";
6
+ import https from "https";
7
+ import url from 'url';
8
+ import { WebSocketServer } from "ws";
9
+ import fs from "fs";
10
+ var netFaces = os.networkInterfaces();
11
+
12
+ function createCert() {
13
+
14
+ var certPath = "./generated-cert-1";
15
+
16
+ if(fs.existsSync(certPath)) {
17
+ return JSON.parse(fs.readFileSync(certPath, { encoding: "utf8", flag: "r" }));
18
+ }
19
+
20
+ var forge = require('node-forge');
21
+ var pki = forge.pki;
22
+
23
+ // generate a key pair or use one you have already
24
+ var keys = pki.rsa.generateKeyPair(2048);
25
+
26
+ // create a new certificate
27
+ var cert = pki.createCertificate();
28
+
29
+ // fill the required fields
30
+ cert.publicKey = keys.publicKey;
31
+ cert.serialNumber = '01';
32
+ cert.validity.notBefore = new Date();
33
+ cert.validity.notAfter = new Date();
34
+ cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 20);
35
+
36
+ const altNames = [{ type: 7, ip: "127.0.0.1"}];
37
+
38
+ for(let i=1;i<255;i++) {
39
+ altNames.push({ type: 7, ip: `192.168.0.${i}`});
40
+ altNames.push({ type: 7, ip: `192.168.1.${i}`});
41
+ }
42
+
43
+ // use your own attributes here, or supply a csr (check the docs)
44
+ var attrs = [{
45
+ name: 'commonName',
46
+ value: 'dev.web-atoms.in'
47
+ },
48
+ {
49
+ name: 'countryName',
50
+ value: 'IN'
51
+ }, {
52
+ shortName: 'ST',
53
+ value: 'Maharashtra'
54
+ }, {
55
+ name: 'localityName',
56
+ value: 'Navi Mumbai'
57
+ }, {
58
+ name: 'organizationName',
59
+ value: 'NeuroSpeech Technologies Pvt Ltd'
60
+ }, {
61
+ shortName: 'OU',
62
+ value: 'Test'
63
+ }];
64
+
65
+ // here we set subject and issuer as the same one
66
+ cert.setSubject(attrs);
67
+ cert.setIssuer(attrs);
68
+ cert.setExtensions([{
69
+ name: "subjectAltName",
70
+ altNames
71
+ }]);
72
+
73
+ // the actual certificate signing
74
+ cert.sign(keys.privateKey);
75
+
76
+ // now convert the Forge certificate to PEM format
77
+ var pem = pki.certificateToPem(cert);
78
+ var pkey = pki.privateKeyToPem(keys.privateKey)
79
+ var c = { key: pkey, cert: pem };
80
+
81
+ fs.writeFileSync( certPath, JSON.stringify(c), "utf8");
82
+ return c;
83
+ }
84
+
85
+ function listen(port, ssl?) {
86
+
87
+ var server = ssl ? https.createServer(createCert(), app) : http.createServer(app);
88
+
89
+ var wss = new WebSocketServer({ noServer: true });
90
+
91
+ const dss = new WebSocketServer({ noServer: true });
92
+
93
+ server.on("error", (error) => {
94
+ console.error(error);
95
+ })
96
+
97
+ server.on("upgrade", function upgrade(request, socket, head) {
98
+ const pathname = url.parse(request.url).pathname;
99
+
100
+ if (pathname === "/__debug" || pathname.startsWith('/__debug/')) {
101
+ dss.handleUpgrade(request, socket, head, function done(ws) {
102
+ dss.emit('connection', ws, request);
103
+ });
104
+ } else if (pathname === '/__listen') {
105
+ wss.handleUpgrade(request, socket, head, function done(ws) {
106
+ wss.emit('connection', ws, request);
107
+ });
108
+ } else {
109
+ console.error("Forwarding further.. " + pathname);
110
+ // socket.destroy();
111
+ socket.on("error", (error) => console.error(error));
112
+ }
113
+ });
114
+
115
+ server.listen(port,() => {
116
+ Object.keys(netFaces).forEach(function (dev) {
117
+ netFaces[dev].forEach(function (details) {
118
+ if (details.family === 'IPv4') {
119
+ if (ssl) {
120
+ console.log((' https://' + details.address + ':' + colors.cyan(port.toString())));
121
+ } else {
122
+ console.log((' http://' + details.address + ':' + colors.cyan(port.toString())));
123
+ }
124
+ }
125
+ });
126
+ });
127
+
128
+
129
+ return console.log(colors.green("Server has started "));
130
+ });
131
+ }
132
+
133
+ portfinder.basePort = 8080;
134
+ portfinder.getPort(function (err, port) {
135
+ if (err) {
136
+ throw err;
137
+ }
138
+ listen(port);
139
+ });
140
+ portfinder.getPort(function (err, port) {
141
+ if (err) {
142
+ throw err;
143
+ }
144
+ listen(port, true);
145
+ });
146
+
@@ -0,0 +1,4 @@
1
+ date-view {
2
+ display: flex;
3
+ color: green;
4
+ }
@@ -0,0 +1,29 @@
1
+ import DateTime from "@web-atoms/date-time/dist/DateTime.js";
2
+ import "./TestView.css";
3
+
4
+ export default class DateView extends HTMLElement {
5
+
6
+ connectedCallback() {
7
+ setInterval(() => {
8
+ const now = DateTime.now;
9
+ this.textContent = now.toJSON();
10
+ }, 1000);
11
+ }
12
+
13
+ }
14
+
15
+ customElements.define("date-view", DateView);
16
+
17
+
18
+ (window as any).ESMPack = {
19
+ async render(imports: { default: any }, cs: HTMLScriptElement) {
20
+ const view = new imports.default();
21
+ cs.replaceWith(view);
22
+ },
23
+ installStyleSheet(src) {
24
+ const link = document.createElement("link");
25
+ link.rel = "stylesheet";
26
+ link.href = src;
27
+ document.head.appendChild(link);
28
+ }
29
+ };
package/tsconfig.json CHANGED
@@ -16,7 +16,8 @@
16
16
  "ES2018",
17
17
  "ES2021.WeakRef",
18
18
  "esnext.disposable",
19
- "ES2021.String"
19
+ "ES2021.String",
20
+ "DOM"
20
21
  ]
21
22
  },
22
23
  "include": [