Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/content/docs/integrations/better-auth.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ sidebar:
Use your [Better Auth](https://better-auth.com/) instance with oRPC's [context](/docs/context) and [middleware](/docs/middleware). No extra package is needed.

:::tip
You may need to forward Better Auth's [response headers](https://better-auth.com/docs/concepts/api#getting-headers), such as a refreshed session cookie. The [Response Headers Plugin](/docs/plugins/response-headers) can help unless you use the [Batch Plugin](/docs/plugins/batch).
You may need to forward Better Auth's [response headers](https://better-auth.com/docs/concepts/api#getting-headers), such as a refreshed session cookie. The [Response Headers Plugin](/docs/plugins/response-headers) can help.
:::

## Resolve the Session in Middleware
Expand Down
2 changes: 2 additions & 0 deletions apps/content/docs/migrations/from-v1.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,8 @@ const batchPlugin = new BatchLinkPlugin({

</CodeGroup>

The `mode` option was removed. The server now starts the batch response once every procedure has responded, so it can carry their [headers](/docs/plugins/batch#response-headers), and [streams](/docs/plugins/batch#streaming-responses) only when a procedure returns a stream.

:::warning
Some cases still need to skip batching, for example procedures that rely on [Hibernation](/docs/integrations/hibernation), which cannot work through batched responses. For those, use `filter`. Its meaning is inverted compared to `exclude`: `exclude` returned `true` to skip batching, while `filter` returns `false` to skip batching. Negate your predicate when migrating.

Expand Down
2 changes: 1 addition & 1 deletion apps/content/docs/plugins/batch-response-compression.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ The whole envelope is compressed, binary subresponses included. Leave this plugi

## Why a Node.js Plugin

A streaming batch sends each response as soon as its procedure resolves. A compressor that cannot flush would hold every early response in its buffer until the slowest one finished, trading streaming for compression. The web [CompressionStream](https://developer.mozilla.org/en-US/docs/Web/API/CompressionStream) has no flush, so this plugin uses [zlib](https://nodejs.org/api/zlib.html) and ends each write with a sync flush instead. The few bytes each flush costs are what keep the batch streaming, [keep-alive frames](/docs/plugins/batch#keep-alive-timer) included.
A streaming batch sends each message of its streams as soon as it is ready. A compressor that cannot flush would hold those messages in its buffer until the stream ended, trading streaming for compression. The web [CompressionStream](https://developer.mozilla.org/en-US/docs/Web/API/CompressionStream) has no flush, so this plugin uses [zlib](https://nodejs.org/api/zlib.html) and ends each write with a sync flush instead. The few bytes each flush costs are what keep the batch streaming, [keep-alive frames](/docs/plugins/batch#keep-alive-timer) included.

## Client

Expand Down
46 changes: 5 additions & 41 deletions apps/content/docs/plugins/batch.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,32 +56,13 @@ const cors = new CORSHandlerPlugin({

:::

## Response Modes
## Streaming Responses

By default, the plugin uses `streaming` mode. Responses are sent as soon as they are ready, so one slow request does not block the rest of the batch.

If your environment does not support streaming responses, such as some serverless platforms or older browsers, switch to `buffered` mode instead. In this mode, all responses are collected and sent together, unless a procedure returns an [AsyncIteratorObject](/docs/async-iterator-object) or a [`ReadableStream`](/docs/binary-data). Such a stream can stay open indefinitely, so the batch switches to streaming as soon as one is returned: the server writes out the responses collected so far, then sends the rest as they are ready. If your client cannot read streamed responses, keep these procedures out of the batch with [`filter`](#filtering-requests).

```ts
const link = new RPCLink({
url: '/rpc',
plugins: [
new BatchLinkPlugin({
mode: 'buffered',
groups: [
{
condition: () => true,
context: {},
},
],
}),
],
})
```
The server starts the batch response once every procedure has responded, so it can carry their [headers](#response-headers). The response streams if one of them returned an [AsyncIteratorObject](/docs/async-iterator-object) or a [`ReadableStream`](/docs/binary-data). If your client cannot read streamed responses, keep these procedures out of the batch with [`filter`](#filtering-requests).

### Keep-Alive Timer

In **streaming** mode, or once a buffered batch switches to streaming, long-running batch responses may remain idle for extended periods. The server plugin can send keep-alive frames to keep the connection alive.
A streaming batch response may stay idle for long periods. The server plugin can send keep-alive frames to keep the connection alive.

```ts
const handler = new RPCHandler(router, {
Expand Down Expand Up @@ -238,26 +219,9 @@ const link = new RPCLink({
Per-request data passed through the link's [`headers` option](/docs/rpc/link#url-and-header-options) is resolved for each request, so it is safe without `scope`.
:::

## Limitations
## Response Headers

Cookies set in a batched call are never stored, because the browser only reads headers from the batch response itself, not from each subresponse. Send procedures that set cookies outside the batch:

```ts
const link = new RPCLink({
url: '/rpc',
plugins: [
new BatchLinkPlugin({
filter: ({ path }) => path[0] !== 'auth', // auth procedures set cookies
groups: [
{
condition: () => true,
context: {},
},
],
}),
],
})
```
The batch response carries the cookies and `Vary` fields of its subresponses, and the headers they all share. Other headers stay on their subresponse. To change what stays on each subresponse, set the server plugin's `mapSubresponse` option.

## Learn More

Expand Down
Loading
Loading