Meros: Multipart Response Utility

1.3.2 · active · verified Sun Apr 19

Meros is a lightweight (642B gzipped) utility designed to simplify the parsing of `multipart/mixed` HTTP responses, a common pattern in technologies like GraphQL for deferred or streamed results. Currently at version 1.3.2, the project appears actively maintained with a stable release cadence. Its key differentiators include a zero-dependency runtime, a minimal footprint, high performance, and seamless integration with `fetch` and `rxjs`. It supports both Node.js (requiring `node >=13`) and browser environments, automatically parsing JSON content within parts. Meros returns an `AsyncGenerator` for `multipart/mixed` responses, or the original `Response` object for other content types, offering flexibility for use in middleware or chained `fetch` calls.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates fetching a response, processing it with `meros`, and gracefully handling both `multipart/mixed` and non-multipart (e.g., JSON) responses using an async generator pattern.

import { meros } from 'meros';

async function fetchAndProcessMultipart() {
  // Simulate a multipart/mixed response or a regular JSON response
  // In a real application, replace with your actual fetch call
  const mockFetch = async (url: string) => {
    if (url === '/api/multipart') {
      // Example multipart response
      return new Response(
        `--boundary\r\nContent-Type: application/json\r\n\r\n{"data": "part1"}\r\n--boundary\r\nContent-Type: text/plain\r\n\r\nhello from part 2\r\n--boundary--`,
        {
          headers: { 'Content-Type': 'multipart/mixed; boundary=boundary' }
        }
      );
    } else {
      // Example non-multipart JSON response
      return new Response(JSON.stringify({ message: 'Not multipart' }), {
        headers: { 'Content-Type': 'application/json' }
      });
    }
  };

  try {
    const response = await mockFetch('/api/multipart'); // Try with '/api/json' to see the other path
    const parts = await meros(response);

    if (parts && typeof (parts as any)[Symbol.asyncIterator] === 'function') {
      console.log('Processing multipart response:');
      for await (const part of parts) {
        if (part.json) {
          console.log('  JSON Part:', part.body);
        } else {
          console.log('  Text/Other Part:', new TextDecoder().decode(part.body as Uint8Array));
        }
      }
    } else {
      console.log('Not a multipart response, processing as regular response:');
      const data = await (parts as Response).json();
      console.log('  Response Data:', data);
    }
  } catch (error) {
    console.error('Error fetching or processing:', error);
  }
}

fetchAndProcessMultipart();

view raw JSON →