All Projects → maraisr → meros

maraisr / meros

Licence: MIT License
🪢 A fast utility that makes reading multipart responses simple

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to meros

Scikit Multiflow
A machine learning package for streaming data in Python. The other ancestor of River.
Stars: ✭ 485 (+344.95%)
Mutual labels:  stream, streaming-data
Node Fetch
A light-weight module that brings the Fetch API to Node.js
Stars: ✭ 7,176 (+6483.49%)
Mutual labels:  fetch, stream
Saber
Window-Based Hybrid CPU/GPU Stream Processing Engine
Stars: ✭ 35 (-67.89%)
Mutual labels:  stream, streaming-data
godsend
A simple and eloquent workflow for streaming messages to micro-services.
Stars: ✭ 15 (-86.24%)
Mutual labels:  stream, streaming-data
Optbinning
Optimal binning: monotonic binning with constraints. Support batch & stream optimal binning
Stars: ✭ 79 (-27.52%)
Mutual labels:  stream, streaming-data
multipart-read-stream
Read a multipart stream over HTTP
Stars: ✭ 13 (-88.07%)
Mutual labels:  stream, multipart
psql-streamer
Stream database events from PostgreSQL to Kafka
Stars: ✭ 37 (-66.06%)
Mutual labels:  stream
node-streamify
Streamify helps you easily provide a streaming interface for your code.
Stars: ✭ 51 (-53.21%)
Mutual labels:  stream
lectures
My free and open source tutorials/books on JS and Java 📖 🌹📚
Stars: ✭ 35 (-67.89%)
Mutual labels:  stream
RoadToTop50-Methodology
Methodology notes for web and infrastructure (Windows/Linux) testing.
Stars: ✭ 32 (-70.64%)
Mutual labels:  stream
web-streams-polyfill
Web Streams, based on the WHATWG spec reference implementation
Stars: ✭ 198 (+81.65%)
Mutual labels:  stream
Streamator
A Spectator Specifically build for Content Creation and Streaming
Stars: ✭ 18 (-83.49%)
Mutual labels:  stream
TogetherStream
A social and synchronized streaming experience
Stars: ✭ 16 (-85.32%)
Mutual labels:  stream
Stream-to-VLC
Tampermonkey script that uses a custom URI scheme to view streams in VLC.
Stars: ✭ 20 (-81.65%)
Mutual labels:  stream
mongoose-gridfs
mongoose gridfs on top of new gridfs api
Stars: ✭ 79 (-27.52%)
Mutual labels:  stream
AzuraRelay
A "relay in a box" containing a lightweight web application and Icecast servers that can connect to and relay an AzuraCast parent instance.
Stars: ✭ 20 (-81.65%)
Mutual labels:  relay
stream
Stream. Curating your streams (MIT) License
Stars: ✭ 15 (-86.24%)
Mutual labels:  stream
stream
Stream API for Go.
Stars: ✭ 43 (-60.55%)
Mutual labels:  stream
async-script-loader
Asynchronous script loading for SPAs
Stars: ✭ 15 (-86.24%)
Mutual labels:  defer
spark-streaming-visualize
Simple demonstration of how to build a complex real time machine learning visualization tool.
Stars: ✭ 16 (-85.32%)
Mutual labels:  streaming-data

meros



npm add meros makes reading multipart responses simple

downloads size

Features

  • No dependencies
  • Seemless api
  • Super performant
  • Supports any1 content-type
  • preamble and epilogue don't yield
  • Browser/Node Compatible
  • Plugs into existing libraries like Relay and rxjs

🚀 Usage

Visit /examples for more info!

// Relies on bundler/environment detection
import { meros } from 'meros';

const parts = await fetch('/api').then(meros);

// As a simple Async Generator
for await (const part of parts) {
  // Do something with this part
}

// Used with rxjs streams
from(parts).subscribe((part) => {
  // Do something with it
});

Specific Environment

Browser

import { meros } from 'meros/browser';
// import { meros } from 'https://cdn.skypack.dev/meros';

const parts = await fetch('/api').then(meros);

Node

import http from 'http';
import { meros } from 'meros/node';

const response = await new Promise((resolve) => {
  const request = http.get(`http://example.com/api`, (response) => {
    resolve(response);
  });
  request.end();
});

const parts = await meros(response);

🔎 API

Meros offers two flavours, both for the browser and for node; but their api's are fundamentally the same.

Note: The type Response is used loosely here and simply alludes to Node's IncomingMessage or the browser's Response type.

meros(response: Response, options?: Options)

Returns: Promise<Response | AsyncGenerator<Part | Part[]>

Meros returns a promise that will resolve to an AsyncGenerator if the response is of multipart/mixed mime, or simply returns the Response if something else; helpful for middlewares. The idea here being that you run meros as a chain off fetch.

fetch('/api').then(meros);

If the content-type is NOT a multipart, then meros will resolve with the response argument.

Example on how to handle this case
import { meros } from 'meros';

const response = await fetch('/api'); // Assume this isnt multipart
const parts = await meros(response);

if (parts[Symbol.asyncIterator] < 'u') {
  for await (const part of parts) {
    // Do something with this part
  }
} else {
  const data = await parts.json();
}

each Part gives you access to:

  • json: boolean ~ Tells you the body would be a JavaScript object of your defined generic T.
  • headers: object ~ A key-value pair of all headers discovered from this part.
  • body: T | Fallback ~ Is the body of the part, either as a JavaScript object (noted by json) or the base type of the environment (Buffer | string, for Node and Browser respectively).

options.multiple: boolean

Default: false

Setting this to true will yield once for all available parts of a chunk, rather than yielding once per part. This is an optimization technique for technologies like GraphQL where rather than commit the payload to the store, to be added-to in the next process-tick we can simply do that synchronously.

Important: This will alter the behaviour and yield arrays—than yield payloads.

const chunks = await fetch('/api').then((response) => meros(response, { multiple: true }));

// As a simple Async Generator
for await (const parts of chunks) {
  for (const part of parts) {
    // Do something with this part, maybe aggregate?
  }
}

💨 Benchmark

via the /bench directory with Node v16.11.0

Validation :: node
✔ meros
✘ it-multipart (FAILED @ "should match reference patch set")

Benchmark :: node
  meros                     x 262,515 ops/sec ±2.45% (77 runs sampled)
  it-multipart              x 165,562 ops/sec ±0.99% (79 runs sampled)

Validation :: browser
✔ meros
✘ fetch-multipart-graphql (FAILED @ "should match reference patch set")

Benchmark :: browser
  meros                     x 864,124 ops/sec ±0.77% (80 runs sampled)
  fetch-multipart-graphql   x 283,296 ops/sec ±0.96% (82 runs sampled)

🎒 Notes

Why the name? meros comes from Ancient Greek μέρος méros, meaning "part".

This library aims to implement RFC1341 in its entirety, however we aren't there yet. That being said, you may very well use this library in other scenarios like streaming in file form uploads.

Another goal here is to aide in being the defacto standard transport library to support @defer and @stream GraphQL directives

Caveats

  • No support the /alternative , /digest or /parallel subtype at this time.
  • No support for nested multiparts

Thanks

Special thanks to Luke Edwards for performance guidance and high level api design.

License

MIT © Marais Rossouw

Footnote

1: By default, we'll look for JSON, and parse that for you. If not, we'll give you the body as what was streamed.

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].