---
changelog:
  category: Release
  version: 1.10.0
date: '2025-10-20T11:50:08Z'
seo:
  description: >-
    The Publisher is a helper that enables you to listen to and publish events
    to subscribers. Combined with the Event Iterator, it allows you to build
    streaming…
title: v1.10.0
type: changelog
---
### Publisher helper [docs](https://orpc.dinwwwh.com/docs/helpers/publisher)

The Publisher is a helper that enables you to listen to and publish events to subscribers. Combined with the [Event Iterator](https://orpc.dinwwwh.com/docs/client/event-iterator), it allows you to build streaming responses, real-time updates, and server-sent events with minimal requirements.

```ts
const publisher = new MemoryPublisher<{
  'something-updated': {
    id: string
  }
}>()

const live = os
  .handler(async function* ({ input, signal, lastEventId }) {
    const iterator = publisher.subscribe('something-updated', { signal, lastEventId })
    for await (const payload of iterator) {
      // Handle payload here or yield directly to client
      yield payload
    }
  })

const publish = os
  .input(z.object({ id: z.string() }))
  .handler(async ({ input }) => {
    await publisher.publish('something-updated', { id: input.id })
  })
  ```
  
  #### Available Adapters
  
  | Name                    | Resume Support | Description                                                      |
| ----------------------- | -------------- | ---------------------------------------------------------------- |
| `MemoryPublisher`       | ✅             | A simple in-memory publisher                                     |
| `IORedisPublisher`      | ✅             | Adapter for [ioredis](https://github.com/redis/ioredis)          |
| `UpstashRedisPublisher` | ✅             | Adapter for [Upstash Redis](https://github.com/upstash/redis-js) |


### `eventIteratorToUnproxiedDataStream` util

Prefer using `eventIteratorToUnproxiedDataStream` over `eventIteratorToStream` when integrating oRPC with the AI SDK. The AI SDK uses `structuredClone` internally, which doesn't support proxied data. Since oRPC may proxy events to attach metadata, you should unproxy them before passing to the AI SDK.

```ts
const { messages, sendMessage, status } = useChat({
  transport: {
    async sendMessages(options) {
      return eventIteratorToUnproxiedDataStream(await client.chat({
        chatId: options.chatId,
        messages: options.messages,
      }, { signal: options.abortSignal }))
    },
    reconnectToStream(options) {
      throw new Error('Unsupported')
    },
  },
})
  ```

### &nbsp;&nbsp;&nbsp;🚀 Features

- **client, server**: Add eventIteratorToUnproxiedDataStream util &nbsp;-&nbsp; by @dinwwwh in https://github.com/middleapi/orpc/issues/1110 [<samp>(e91d2)</samp>](https://github.com/middleapi/orpc/commit/e91d2fd2)
- **publisher**: Memory, ioredis, upstash redis publishers &nbsp;-&nbsp; by @dinwwwh and **Joonseo Lee** in https://github.com/middleapi/orpc/issues/1094 [<samp>(22ef1)</samp>](https://github.com/middleapi/orpc/commit/22ef10a4)

### &nbsp;&nbsp;&nbsp;🏎 Performance

- **durable-iterator**: Improve resume events cleanup logic &nbsp;-&nbsp; by @dinwwwh in https://github.com/middleapi/orpc/issues/1102 [<samp>(425e0)</samp>](https://github.com/middleapi/orpc/commit/425e040c)

> [!TIP]
> If you find oRPC valuable and would like to support its development, you can do so [here](https://github.com/sponsors/dinwwwh).

##### &nbsp;&nbsp;&nbsp;&nbsp;[View changes on GitHub](https://github.com/middleapi/orpc/compare/v1.9.4...v1.10.0)
