UNPKG

piecemeal

Version:

Effortless incrementally deliver your data

133 lines (91 loc) 3.75 kB
<div align="center"> <h1><img src="./shots/logo.svg" alt="piecemeal"/></h1> <p><code>npm add piecemeal</code> makes incremental delivery possible</p> <hr /> <div> <a href="https://github.com/maraisr/piecemeal/actions/workflows/ci.yml"> <img src="https://github.com/maraisr/piecemeal/actions/workflows/ci.yml/badge.svg"/> </a> <a href="https://npm-stat.com/charts.html?package=piecemeal"> <img src="https://badgen.net/npm/dm/piecemeal?labelColor=black&color=black" alt="downloads"/> </a> <a href="https://packagephobia.com/result?p=piecemeal"> <img src="https://badgen.net/packagephobia/install/piecemeal?labelColor=black&color=black" alt="size"/> </a> <a href="https://bundlephobia.com/result?p=piecemeal"> <img src="https://badgen.net/bundlephobia/minzip/piecemeal?labelColor=black&color=black" alt="size"/> </a> </div> </div> ## Features - **Lightweight** — _Does **not** include any dependencies [see](https://npm.anvaka.com/#/view/2d/piecemeal)_. - **Familiar** — _plugs into any `node:http` or `workers` based environment._ - **Incredible DX** — _passing only an `AsyncIterable | Iterable`._ ## ⚙️ Install ```sh npm add piecemeal ``` ## 🚀 Usage > Visit [/examples](/examples) for more info! #### _Workers_ ```ts import * as Piecemeal from 'piecemeal/worker'; // Some sort of data access // ~> here we read from KV, but can be anything async function* get_data(binding: KV.Namespace) { const list = await DATA.list(); for await (let item of list.keys) { yield await DATA.get(item); } } // A handler you'd typically give a Module or Service Worker const handler = (request, env, context) => { // Notice we're not awaiting or spreading this iterable const data = get_data(context.bindings.DATA); // Sets up our stream and constructs the Response const { pipe, response } = Piecemeal.stream(data); // Defers the execution of the iterable, so we respond super quick context.waitUntil(pipe()); return response; }; ``` #### _Node_ ```ts import { createServer } from 'node:http'; import * as Piecemeal from 'piecemeal/node'; // An example of some method to retreive some database data async function* get_data() { const keys = await db.fetchAllKeys(); for await (let key of keys) { yield await db.read(key); } } createServer((req, res) => { // Notice we're not awaiting or spreading this iterable const data = get_data(); // Creates a streams — and kicks off the iterable. // assumes JSON (can override) const stream = Piecemeal.stream(data); // Pipes the stream directly to a ServerResponse stream.pipe(res); }).listen(8080); ``` ## 🔎 API #### Module: [`piecemeal/worker`](./src/worker.ts) The main module used by [Cloudflare Workers](https://workers.cloudflare.com/) — or any [Service Worker API](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API). > Example over at [/examples/workers](/examples/workers) #### Module: [`piecemeal/node`](./src/node.ts) The main module used for a `node` runtime and plugs directly into `node:http` modules. > Example over at [/examples/polka](/examples/polka) #### Module: [`piecemeal/message`](./src/message.ts) A module used to construct messages. Messages are the partial _bits-of-data_ flushed in increments. #### Module: [`piecemeal`](./src/index.ts) A main module one can use to build out custom runtimes — exposes all the building blocks to `generate` a stream supplying the Iterable and a write method. ## 🙊 Caveats - Workers doesn't abort any iterables if connection is dropped. 😔 ## Related - [meros](https://github.com/maraisr/meros) — makes reading multipart responses simple ## License MIT © [Marais Rossouw](https://marais.io)