Skip to content

luwes/wesc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

bbf4a52 · Apr 13, 2024
Feb 21, 2024
Apr 13, 2024
Feb 3, 2024
Jan 28, 2024
Jan 28, 2024
Feb 3, 2024
Jan 28, 2024
Apr 13, 2024
Feb 3, 2024
Apr 13, 2024
Feb 3, 2024
Apr 13, 2024
Apr 13, 2024

Repository files navigation

WeSC

We are the Superlative Components!

Goals

  • HTML first (The Rule of Least Power)
  • Stay close to web standards
  • Define and create a superlative component authoring experience
  • Server language agnostic

A streaming web component bundler written in Rust using the lol-html parser.

The idea is to create a single-file HTML component format and builder that builds the HTML result super fast (streaming, low memory) and is server language agnostic.

Features

  • Streaming HTML bundler
  • Web component definition
  • Default and named slots with fallback content
  • Declarative Shadow DOM
  • CSS bundling
  • JS bundling

Example

wesc ./index.html

Syntax

index.html

<!doctype html>
<html>
  <head>
    <link rel="definition" name="w-card" href="./components/card.html">
  </head>
  <body>
    <w-card>
      <h3 slot="title">Title</h3>
      Description
    </w-card>
  </body>
</html>

components/card.html

<template>
<!-- or <template shadowrootmode="open"> -->
  <style>
    @scope {
      h3 {
        color: red;
      }
    }
  </style>
  <div>
    <h3><slot name="title">Add a slotted title</slot></h3>
    <p><slot>Add default slotted content</slot></p>
  </div>
</template>

<style>
  w-card {
    display: block;
  }
</style>

<!-- TODO: bundle to a global scripts.js -->
<script>
  class WCard extends HTMLElement {
    connectedCallback() {
      console.log('w-card connected');
    }
  }
  customElements.define('w-card', WCard);
</script>

WeSC DOM - Custom element server-side rendering

Custom elements are a crucial part of reaching these goals. The first problem WeSC is aiming to solve is rendering DSD (declarative shadow DOM) in a simple and approachable way for most use cases.

Examples

Have a look at the examples to see if your use case is handled and feel free to open an issue if not.

Simple Node usage

npm install wesc

index.js

import { promises as fs } from 'fs';
import { renderToString } from 'wesc/dom/server';

// Import web component library
import 'media-chrome';

// Process full page
let html = await fs.readFile('./app.html');

let out = await renderToString(html);

await fs.writeFile('./index.html', out);

app.html

<!-- ... -->
<media-controller>
  <video
    playsinline
    slot="media"
    src="https://stream.mux.com/A3VXy02VoUinw01pwyomEO3bHnG4P32xzV7u1j1FSzjNg/high.mp4"
  ></video>
  <media-poster-image
    slot="poster"
    src="https://image.mux.com/A3VXy02VoUinw01pwyomEO3bHnG4P32xzV7u1j1FSzjNg/thumbnail.jpg"
    placeholdersrc="data:image/jpeg;base64,/9j/2wBDABQODxIPDRQSEBIXFRQYHjIhHhwcHj0sLiQySUBMS0dARkVQWnNiUFVtVkVGZIhlbXd7gYKBTmCNl4x9lnN+gXz/2wBDARUXFx4aHjshITt8U0ZTfHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHz/wAARCAAUADADASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAECBAP/xAAdEAEBAAEEAwAAAAAAAAAAAAAAARECAxITFCFR/8QAGQEAAwADAAAAAAAAAAAAAAAAAAEDAgQF/8QAGBEBAQEBAQAAAAAAAAAAAAAAAAETERL/2gAMAwEAAhEDEQA/ANeC4ldyI1b2EtIzzrrIqYZLvl5FGkGdbfQzGPvo76WsPxXLlfqbaA5va2iVJADgPELACsD/2Q=="
  ></media-poster-image>
  <media-loading-indicator slot="centered-chrome" noautohide></media-loading-indicator>
  <media-control-bar>
    <media-play-button></media-play-button>
    <media-mute-button></media-mute-button>
    <media-volume-range></media-volume-range>
    <media-time-display></media-time-display>
    <media-time-range></media-time-range>
    <media-duration-display></media-duration-display>
    <media-playback-rate-button></media-playback-rate-button>
    <media-fullscreen-button></media-fullscreen-button>
  </media-control-bar>
</media-controller>
<!-- ... -->

HTML output

view-source:https://wesc-node.netlify.app

Related