atoms-element v5.0.0

#js

git clone https://git.pyrossh.dev/atoms-element

A simple web component library for defining your custom elements. It works on both client and server.


examples/server.js
a3cc1df 1
import http from 'http';
a3cc1df 2
import fs from 'fs';
4c11234 3
import path from 'path';
a3cc1df 4
import { fileURLToPath } from 'url';
67e0dfd 5
import { dirname } from 'path';
24398b1 6
import renderPage from './pages/index.js';
a3cc1df 7
a3cc1df 8
const __filename = fileURLToPath(import.meta.url);
a3cc1df 9
const __dirname = dirname(__filename);
4c11234 10
const rootDir = path.join(__dirname, '..');
a3cc1df 11
const port = process.argv[2] || 3000;
24398b1 12
const elements = ['app-counter.js', 'app-total.js'];
67e0dfd 13
const srcMap = {
4c11234 14
  '/index.js': `${rootDir}/index.js`,
a3cc1df 15
};
24398b1 16
elements.forEach((el) => {
24398b1 17
  srcMap['/elements/' + el] = `${__dirname}/elements/${el}`;
24398b1 18
});
a3cc1df 19
e955350 20
// lit-html and @lit-labs/ssr-client are real npm dependencies (not vendored),
e955350 21
// so the browser needs an import map for every bare specifier reachable from
e955350 22
// index.js — including ones used by their own internal files, since the
e955350 23
// import map is global to the page, not scoped per-package the way Node's
e955350 24
// node_modules resolution is. The packages' files are served as-is; their
e955350 25
// own internal imports are all relative, so no other wiring is needed.
4c11234 26
const importMap = {
4c11234 27
  imports: {
4c11234 28
    'lit-html': '/node_modules/lit-html/lit-html.js',
25308a9 29
    'lit-html/directive.js': '/node_modules/lit-html/directive.js',
4c11234 30
    'lit-html/directive-helpers.js': '/node_modules/lit-html/directive-helpers.js',
25308a9 31
    'lit-html/private-ssr-support.js': '/node_modules/lit-html/private-ssr-support.js',
4c11234 32
    'lit-html/directives/unsafe-html.js': '/node_modules/lit-html/directives/unsafe-html.js',
e955350 33
    'lit-html/directives/class-map.js': '/node_modules/lit-html/directives/class-map.js',
e955350 34
    'lit-html/directives/style-map.js': '/node_modules/lit-html/directives/style-map.js',
25308a9 35
    '@lit-labs/ssr-client': '/node_modules/@lit-labs/ssr-client/index.js',
4c11234 36
  },
4c11234 37
};
4c11234 38
const nodeModulesDir = path.join(rootDir, 'node_modules');
4c11234 39
a3cc1df 40
http
be4ce51 41
  .createServer((req, res) => {
649634e 42
    if (req.url.includes('/api/posts')) {
649634e 43
      const parts = req.url.split('/');
649634e 44
      const id = parts[parts.length - 1];
649634e 45
      res.setHeader('Content-type', 'application/json');
649634e 46
      res.end(
649634e 47
        JSON.stringify({
649634e 48
          id,
649634e 49
          title: `post ${id}`,
649634e 50
          description: ` description ${id}`,
649634e 51
        }),
649634e 52
      );
649634e 53
      return;
649634e 54
    }
a3cc1df 55
    if (req.url === '/') {
a3cc1df 56
      res.statusCode = 200;
a3cc1df 57
      res.setHeader('Content-type', 'text/html');
8f1fc6d 58
      const html = renderPage({
8f1fc6d 59
        lang: 'en',
8f1fc6d 60
        props: {
8f1fc6d 61
          config: { lang: 'en', title: 'Counter App' },
8f1fc6d 62
        },
4c11234 63
        headScript: `<script type="importmap">${JSON.stringify(importMap)}</script>`,
a3cc1df 64
        bodyScript: `
a3cc1df 65
          <script type="module">
24398b1 66
          ${elements.map((el) => `import './elements/${el}';`).join('\n')}
a3cc1df 67
          </script>
a3cc1df 68
        `,
a3cc1df 69
      });
a3cc1df 70
      res.end(html);
a3cc1df 71
      return;
a3cc1df 72
    }
4c11234 73
    if (req.url.startsWith('/node_modules/')) {
4c11234 74
      const relative = req.url.slice('/node_modules/'.length);
4c11234 75
      const filename = path.normalize(path.join(nodeModulesDir, relative));
4c11234 76
      if (filename.startsWith(nodeModulesDir) && fs.existsSync(filename)) {
0000000 77
        res.setHeader('Content-type', filename.endsWith('.css') ? 'text/css' : 'application/javascript');
4c11234 78
        res.end(fs.readFileSync(filename));
4c11234 79
      } else {
4c11234 80
        res.statusCode = 404;
4c11234 81
        res.end();
4c11234 82
      }
4c11234 83
      return;
4c11234 84
    }
67e0dfd 85
    const filename = srcMap[req.url];
ba5668f 86
    if (filename) {
ba5668f 87
      const data = fs.readFileSync(filename);
ba5668f 88
      res.setHeader('Content-type', 'application/javascript');
ba5668f 89
      res.end(data);
4c11234 90
      return;
ba5668f 91
    }
4c11234 92
    res.statusCode = 404;
4c11234 93
    res.end();
a3cc1df 94
  })
a3cc1df 95
  .listen(parseInt(port));
a3cc1df 96
67e0dfd 97
console.log(`Server listening on http://localhost:${port}`);