Socket
Socket
Sign inDemoInstall

meros

Package Overview
Dependencies
2
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    meros

A fast 610B utility that makes reading multipart responses simple


Version published
Maintainers
1
Install size
28.6 kB
Created

Package description

What is meros?

The meros npm package is designed to handle multipart responses in a more convenient and efficient way. It is particularly useful for dealing with GraphQL multipart responses, allowing clients to process parts of the response as they arrive, rather than waiting for the entire response. This can improve performance and user experience in applications that consume streaming APIs or need to handle large, multipart responses.

What are meros's main functionalities?

Parsing GraphQL multipart responses

This code sample demonstrates how to use meros to parse a GraphQL multipart response from a fetch request. It checks if the response is of type 'multipart/mixed' and then uses meros to asynchronously iterate over each part of the response, logging the body of each part if it is JSON.

import { meros } from 'meros';

const response = await fetch('/graphql', {
  body: JSON.stringify({ query }),
  method: 'POST',
});

if (response.headers.get('content-type').includes('multipart/mixed')) {
  const parts = await meros(response);
  for await (const part of parts) {
    if (part.json) {
      console.log(part.body);
    }
  }
}

Other packages similar to meros

Readme

Source

meros

yarn add meros makes reading multipart responses simple


downloads size

⚡ Features

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

⚙️ Install

yarn add meros

🚀 Usage

// Rely on bundler/environment dection
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).pipe(
  tap((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://my-domain/mock-ep`, (response) => {
    resolve(response);
  });
  request.end();
});

const parts = await meros(response);

🎒 Notes

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.

Please note; be sure to define a boundary that can be guaranteed to never collide with things from the body:

Because encapsulation boundaries must not appear in the body parts being encapsulated, a user agent must exercise care to choose a unique boundary.

~ RFC1341 7.2.1

  • meros comes from Ancient Greek μέρος méros, meaning "part".

Caveats

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

🔎 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 returns json
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

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

Benchmark :: node
  meros                     x 289,318 ops/sec ±1.21% (81 runs sampled)
  it-multipart              x 173,136 ops/sec ±0.85% (80 runs sampled)

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

Benchmark :: browser
  meros                     x 1,000,417 ops/sec ±1.41% (81 runs sampled)
  fetch-multipart-graphql   x 353,207 ops/sec ±0.92% (83 runs sampled)

Ran with Node v15.8.0

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

Keywords

FAQs

Last updated on 22 Feb 2021

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc