Streams 
Mearie uses a stream-based architecture for handling GraphQL operations. Understanding this concept helps you work effectively with exchanges and build custom middleware.
What are Streams? 
Streams in Mearie are push-based, reactive data flows similar to observables in RxJS or Wonka. Think of them as pipelines where data flows from source to destination:
Operations → [Exchange 1] → [Exchange 2] → [Exchange 3] → ResultsEach exchange receives a stream of operations, transforms it, and produces a stream of results.
Why Streams? 
Streams provide several key benefits:
Reactive 
Operations flow through the system automatically. When you execute a query, it immediately starts flowing through the exchange pipeline.
Composable 
Exchanges are pure functions that transform streams. You can compose multiple exchanges together, and each operates independently on the stream.
Cancellable 
Streams support cancellation. When you stop listening to results (e.g., component unmounts), the operation is cancelled and resources are cleaned up automatically.
Lazy 
Streams are lazy by default. The exchange pipeline only runs when something subscribes to the results.
Core Concepts 
Source 
A Source is a stream that emits values. In Mearie, operations flow as a source, and results flow back as another source.
type Source<T> = (sink: Sink<T>) => Subscription;Sink 
A Sink receives values from a source. It has two methods:
- next(value)- Receive a value
- complete()- Signal completion
Subscription 
A Subscription allows you to cancel a stream and clean up resources:
const subscription = source(sink);
subscription.unsubscribe(); // Cancel and cleanupHow Exchanges Use Streams 
Every exchange follows this pattern:
type Exchange = (input: ExchangeInput) => ExchangeIO;
type ExchangeIO = (operations: Source<Operation>) => Source<OperationResult>;An exchange:
- Receives a stream of operations
- Transforms them (filter, modify, augment)
- Calls forwardto pass operations to the next exchange
- Transforms the results coming back
- Returns a stream of results
Example Flow 
When you execute a query:
const result$ = client.executeQuery(MyQuery, { id: '123' });Here's what happens:
- Client creates an operation and pushes it to the operations stream
- Operation flows through each exchange in order
- Each exchange can transform the operation or pass it along
- Terminal exchange (http/subscription) executes the request
- Result flows back through exchanges in reverse
- Each exchange can transform the result
- Final result reaches your application
Mental Model 
Think of exchanges as a series of pipes:
     Operations Stream
          ↓
    [dedupExchange]  ← Removes duplicate requests
          ↓
    [cacheExchange]  ← Returns cached data or forwards
          ↓
    [httpExchange]   ← Makes network request
          ↓
     Results StreamEach exchange can:
- Observe operations passing through
- Filter or modify operations
- Add new operations to the stream
- Intercept and cache results
- Transform results
Next Steps 
- Exchanges Guide - Learn how to compose exchanges
- Streams API Reference - Complete API documentation for streams
- Custom Exchanges - Build your own exchanges