All Projects → worker-tools → html

worker-tools / html

Licence: MIT license
HTML templating and streaming response library for Service Worker-like environments such as Cloudflare Workers.

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to html

Php Fetch
A simple, type-safe, zero dependency port of the javascript fetch WebApi for PHP
Stars: ✭ 95 (+131.71%)
Mutual labels:  streams, response, fetch-api
fetch
A fetch API polyfill for React Native with text streaming support.
Stars: ✭ 27 (-34.15%)
Mutual labels:  streams, fetch-api
workers-jwt
Generate JWTs on Cloudflare Workers using the WebCrypto API
Stars: ✭ 67 (+63.41%)
Mutual labels:  workers, cloudflare-workers
penumbra
Encrypt/decrypt anything in the browser using streams on background threads.
Stars: ✭ 100 (+143.9%)
Mutual labels:  streams, whatwg-streams
Fetch Progress Indicators
Progress indicators/bars using Streams, Service Workers, and Fetch APIs
Stars: ✭ 181 (+341.46%)
Mutual labels:  service-worker, fetch-api
natural
Fastest Framework for NodeJS. Written in pure ES6+
Stars: ✭ 30 (-26.83%)
Mutual labels:  workers, cloudflare-workers
cloudflare-worker-graphql-ws-template
A template for WebSockets powered Cloudflare Worker project using graphql-ws
Stars: ✭ 21 (-48.78%)
Mutual labels:  workers, cloudflare-workers
deno-fetch-event-adapter
Dispatches global fetch events using Deno's native http server.
Stars: ✭ 18 (-56.1%)
Mutual labels:  service-worker, cloudflare-workers
edge-mock
Tools for testing and developing CloudFlare worker apps.
Stars: ✭ 49 (+19.51%)
Mutual labels:  service-worker, cloudflare-workers
cloudflare-worker-router
A super lightweight router (1.3K) with middleware support and ZERO dependencies for CloudFlare Workers.
Stars: ✭ 144 (+251.22%)
Mutual labels:  workers, cloudflare-workers
Jfa Pwa Toolkit
⚡️ PWA Features to Any Website (very Fast & Easy)
Stars: ✭ 245 (+497.56%)
Mutual labels:  service-worker
Hnpwa Vanilla
Hacker News PWA implemented using no framework just javascript
Stars: ✭ 245 (+497.56%)
Mutual labels:  service-worker
project-acorn-ssr
A Vue.js SPA built around the WordPress REST API with Vuex, Vue Router, Axios and SSR.
Stars: ✭ 14 (-65.85%)
Mutual labels:  service-worker
chronosjs
JS Channels (Events / Commands / Reqest-Response / Courier) Mechanism
Stars: ✭ 35 (-14.63%)
Mutual labels:  response
So Pwa
A progressive web app to read Stack Overflow content.
Stars: ✭ 235 (+473.17%)
Mutual labels:  service-worker
reqres
Powerful classes for http requests and responses
Stars: ✭ 36 (-12.2%)
Mutual labels:  response
Productivity Frontend
Productivity Application - Kanban Style Productivity Management Application with Customizable Boards, Lists and Cards to Make You More Productive.
Stars: ✭ 234 (+470.73%)
Mutual labels:  service-worker
Ember Service Worker
A pluggable approach to Service Workers for Ember.js
Stars: ✭ 227 (+453.66%)
Mutual labels:  service-worker
Progressive Weather App
A local weather app that fetches weather forecast from Openweathermap.org. A Progressive Web App built with Vue.js.
Stars: ✭ 223 (+443.9%)
Mutual labels:  service-worker
is-pwa-ready
Tracking the status of PWA in Chinese browser
Stars: ✭ 35 (-14.63%)
Mutual labels:  service-worker

Worker HTML

HTML templating and streaming response library for Worker Runtimes such as Cloudflare Workers.

HTML Templating

Templating is done purely in JavaScript using tagged template strings, inspired by hyperHTML and lit-html.

This library is using tagged template strings to create streaming response bodies on the fly, using no special template syntax and giving you the full power of JS for composition.

Examples

String interpolation works just like regular template strings, but all content is sanitized by default:

const helloWorld = 'Hello World!';
const h1El = html`<h1>${helloWorld}</h1>`;

What is known as "partials" in string-based templating libraries are just functions here:

const timeEl = (ts = new Date()) => html`
  <time datetime="${ts.toISOString()}">${ts.toLocalString()}</time>
`;

What is known as "layouts" are just functions as well:

const baseLayout = (title: string, content: HTMLContent) => html`
  <!DOCTYPE html>
  <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>${title}</title>
    </head>
    <body>${content}</body>
  </html>
`;

Layouts can "inherit" from each other, again using just functions:

const pageLayout = (title: string, content: HTMLContent) => baseLayout(title, html`
  <main>
    ${content}
    <footer>Powered by @worker-tools/html</footer>
  </main>
`);

Many more features of string-based templating libraries can be replicated using functions. Most satisfying should be the use of map to replace a whole host of custom looping syntax:

html`<ul>${['Foo', 'Bar', 'Baz'].map(x => html`<li>${x}</li>`)}</ul>`;

Putting it all together:

function handleRequest(event: FetchEvent) {
  const page = pageLayout(helloWorld, html`
    ${h1El}
    <p>The current time is ${timeEl()}.</p>
    <ul>${['Foo', 'Bar', 'Baz'].map(x => html`<li>${x}</li>`)}</ul>
  `));

  return new HTMLResponse(page);
}

self.addEventListener('fetch', ev => ev.respondWith(handleRequest(ev)));

Note that this works regardless of worker runtime: Cloudflare Workers, Service Workers in the browser, and hopefully other Worker Runtimes that have yet to be implemented.

Tooling

Since the use of tagged string literals for HTML is not new (see hyperHTML, lit-html), there exists tooling for syntax highlighting, such as lit-html in VSCode.

Streaming Responses

As a side effect of this approach, responses are streams by default. This means you can use async data, without delaying sending the headers and HTML content.

In the example below, everything up to and including <p>The current time is will be sent immediately, with the reset sent after the API request completes:

function handleRequest(event: FetchEvent) {
  // NOTE: No `await` here!
  const timeElPromise = fetch('https://time.api/now')
    .then(r => r.text())
    .then(t => timeEl(new Date(t)));

  return new HTMLResponse(pageLayout('Hello World!', html`
    <h1>Hello World!</h1>
    <p>The current time is ${timeElPromise}.</p>
  `));
}

While there's ways around the lack of async/await in the above example (namely IIAFEs), @worker-tools/html supports passing async functions as html content directly:

function handleRequest(event: FetchEvent) {
  return new HTMLResponse(pageLayout('Hello World!', html`
    <h1>Hello World!</h1>
    ${async () => {
      const timeStamp = new Date(
        await fetch('https://time.api/now').then(r => r.text())
      );
      return html`<p>The current time is ${timeEl(timeStamp)}.</p>`
    }}
  `));
}

Note that there are some subtle differences compared to the earlier examples.

  • The initial response will include headers and html up to and including <h1>Hello World!</h1>
  • The time API request will not be sent until the headers and html up to and including <h1>Hello World!</h1> have hit the wire.

These follow from the way async/await works, so shouldn't be too surprising to those already familiar with common async/await pitfalls.

If for any reason you don't want to use streaming response bodies, you can use the BufferedHTMLResponse instead, which will buffer the entire body before releasing it to the network.

See Other

You can combine this library with tools from the Worker Tools family such as @worker-tools/response-creators:

import { internalServerError } from '@worker-tools/response-creators';

function handleRequest(event: FetchEvent) {
  return new HTMLResponse(
    pageLayout('Ooops', html`<h1>Something went wrong</h1>`), 
    internalServerError(),
  );
}

You can also see the Worker News source code for an example of how to build an entire web app on the edge using Worker HTML.

Finally, you can read The Joys and Perils of Writing Plain Old Web Apps for a personal account of building web apps in a Web 2.0 way.




This module is part of the Worker Tools collection

Worker Tools are a collection of TypeScript libraries for writing web servers in Worker Runtimes such as Cloudflare Workers, Deno Deploy and Service Workers in the browser.

If you liked this module, you might also like:

  • 🧭 Worker Router --- Complete routing solution that works across CF Workers, Deno and Service Workers
  • 🔋 Worker Middleware --- A suite of standalone HTTP server-side middleware with TypeScript support
  • 📄 Worker HTML --- HTML templating and streaming response library
  • 📦 Storage Area --- Key-value store abstraction across Cloudflare KV, Deno and browsers.
  • 🆗 Response Creators --- Factory functions for responses with pre-filled status and status text
  • 🎏 Stream Response --- Use async generators to build streaming responses for SSE, etc...
  • 🥏 JSON Fetch --- Drop-in replacements for Fetch API classes with first class support for JSON.
  • 🦑 JSON Stream --- Streaming JSON parser/stingifier with first class support for web streams.

Worker Tools also includes a number of polyfills that help bridge the gap between Worker Runtimes:

Fore more visit workers.tools.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].