Skip to main content
The multiple option changes Meros’s yielding behavior to return arrays of parts instead of individual parts, enabling synchronous batch processing.

Why use multiple mode?

Multiple mode is an optimization technique useful when you want to process all available parts in a chunk synchronously, rather than yielding once per part.
This is particularly valuable for technologies like GraphQL where you can commit multiple payloads to the store in a single synchronous operation instead of across multiple process ticks.

Basic usage

Enable multiple mode by setting options.multiple to true:
const chunks = await fetch('/api').then((response) => 
  meros(response, { multiple: true })
);

for await (const parts of chunks) {
  // parts is an array of Part objects
  for (const part of parts) {
    // Process each part in the batch
  }
}

Single mode vs. Multiple mode

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

// Yields once per part
for await (const part of parts) {
  console.log(part.body); // Individual part
}

How it works

The internal implementation determines yielding behavior based on the multiple option:
let is_eager = !options || !options.multiple;

// Later in the code...
if (is_eager) {
  yield tmp;  // Yield individual part immediately
} else {
  payloads.push(tmp);  // Accumulate parts
}

// At chunk boundaries
if (payloads.length) {
  yield payloads;  // Yield all accumulated parts
}
1

Chunk arrives

Meros receives a chunk from the stream
2

Parts extracted

All complete parts in the chunk are extracted and parsed
3

Batch yielded

In multiple mode, all parts are yielded together as an array
4

Synchronous processing

Your code can process all parts synchronously before the next tick

GraphQL example

Multiple mode is ideal for GraphQL @defer and @stream directives:
import { meros } from 'meros';

interface GraphQLResponse {
  data?: any;
  errors?: any[];
  extensions?: any;
}

const chunks = await fetch('/graphql', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ query: '...' })
}).then((response) => meros<GraphQLResponse>(response, { multiple: true }));

for await (const parts of chunks) {
  // Commit all parts to the store synchronously
  const updates = parts.map(part => {
    if (part.json) {
      return part.body.data;
    }
  }).filter(Boolean);
  
  // Single synchronous store update with all data
  store.merge(updates);
}

Performance benefits

// Each part triggers a separate async iteration
for await (const part of parts) {
  store.update(part); // Async boundary
  // Next part waits for next tick
}
  • One async iteration per part
  • Store updates happen across multiple ticks
  • More async overhead

Aggregation pattern

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

for await (const parts of chunks) {
  // Aggregate data from all parts in the chunk
  const aggregated = parts.reduce((acc, part) => {
    if (part.json) {
      return { ...acc, ...part.body };
    }
    return acc;
  }, {});
  
  // Single operation with aggregated data
  processData(aggregated);
}

Choosing the right mode

Use single mode (default) when:
  • You want to react to each part immediately
  • You’re displaying parts as they arrive
  • Each part is independent
Use multiple mode when:
  • You need to batch process parts
  • You’re aggregating data across parts
  • You want to minimize async iterations
  • Working with GraphQL deferred queries

Type differences

import type { Part } from 'meros';

// Single mode
AsyncGenerator<Part<T>>

// Multiple mode
AsyncGenerator<Part<T>[]>
Setting multiple: true changes the yielded type from Part to Part[]. Ensure your code handles arrays appropriately.

Browser and Node.js support

Multiple mode works identically in both environments:
import { meros } from 'meros/browser';

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

Build docs developers (and LLMs) love