Skip to content

Commit c5401b5

Browse files
authored
feat(durable-iterator): rewrite + enchance (#965)
- [x] feat: rewrite - [x] feat: refresh token without re-estimate websocket connection - [x] feat: tags with publish events filter support - [x] feat: support `targets` and `exclude` as callback for filter - [x] fix: should run before retry-plugin to avoid conflict - [x] fix: server-side client, retry-plugin not preserve extra iterator's fields (rpc methods in this case) - [x] test - [x] docs Closes: #993 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced Durable Iterator: end-to-end durable streaming with token-based auth, auto-reconnect, resume/replay, publishEvent, tagging/target/exclude filters, client & handler plugins, and token refresh. * Streaming cancellation via AbortController; added getSignedValue helper and new utilities overlayProxy and fallback. * **Documentation** * Renamed docs/sidebar to “Durable Iterator” and updated streaming examples to show AbortController usage. * **Chores** * Package rename and CI/playground updates for @orpc/experimental-durable-iterator. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 5176631 commit c5401b5

File tree

97 files changed

+6377
-2442
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+6377
-2442
lines changed

.github/workflows/ci.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ jobs:
1414

1515
- uses: pnpm/action-setup@v4
1616

17+
- uses: actions/setup-node@v5
18+
with:
19+
node-version: 22
20+
cache: pnpm
21+
1722
- run: pnpm i
1823

1924
- run: pnpm run lint
@@ -27,6 +32,11 @@ jobs:
2732

2833
- uses: pnpm/action-setup@v4
2934

35+
- uses: actions/setup-node@v5
36+
with:
37+
node-version: 22
38+
cache: pnpm
39+
3040
- run: pnpm i
3141

3242
- run: pnpm run test:coverage
@@ -42,6 +52,11 @@ jobs:
4252

4353
- uses: pnpm/action-setup@v4
4454

55+
- uses: actions/setup-node@v5
56+
with:
57+
node-version: 22
58+
cache: pnpm
59+
4560
- run: pnpm i
4661

4762
- run: pnpm run packages:publish:commit

.github/workflows/release-next.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ jobs:
1515

1616
- uses: pnpm/action-setup@v4
1717

18+
- uses: actions/setup-node@v5
19+
with:
20+
node-version: 22
21+
cache: pnpm
22+
1823
- run: pnpm i
1924

2025
- run: |

.github/workflows/release.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ jobs:
4545

4646
- uses: pnpm/action-setup@v4
4747

48+
- uses: actions/setup-node@v5
49+
with:
50+
node-version: 22
51+
cache: pnpm
52+
4853
- run: pnpm i
4954

5055
- run: |

apps/content/.vitepress/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ export default withMermaid(defineConfig({
180180
collapsed: true,
181181
items: [
182182
{ text: 'AI SDK', link: '/docs/integrations/ai-sdk' },
183-
{ text: 'Durable Event Iterator', link: '/docs/integrations/durable-event-iterator' },
183+
{ text: 'Durable Iterator', link: '/docs/integrations/durable-iterator' },
184184
{ text: 'Hey API', link: '/docs/integrations/hey-api' },
185185
{ text: 'OpenTelemetry', link: '/docs/integrations/opentelemetry' },
186186
{ text: 'Pinia Colada', link: '/docs/integrations/pinia-colada' },

apps/content/docs/client/event-iterator.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,16 @@ for await (const event of iterator) {
2929

3030
## Stopping the Stream Manually
3131

32-
Call `.return()` on the iterator to gracefully end the stream.
32+
You can rely on `signal` or `.return` to stop the iterator.
3333

3434
```ts
35-
const iterator = await client.streaming()
35+
const controller = new AbortController()
36+
const iterator = await client.streaming(undefined, { signal: controller.signal })
3637

38+
// Stop the stream after 1 second
3739
setTimeout(async () => {
38-
// Stop the stream after 1 second
40+
controller.abort()
41+
// or
3942
await iterator.return()
4043
}, 1000)
4144

apps/content/docs/helpers/signing.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Signing is faster than [encryption](/docs/helpers/encryption) but users can view
1212
:::
1313

1414
```ts twoslash
15-
import { sign, unsign } from '@orpc/server/helpers'
15+
import { getSignedValue, sign, unsign } from '@orpc/server/helpers'
1616

1717
const secret = 'your-secret-key'
1818
const userData = 'user123'
@@ -22,8 +22,11 @@ const signedValue = await sign(userData, secret)
2222
// ↑ Original data is visible to users
2323

2424
const verifiedValue = await unsign(signedValue, secret) // 'user123'
25+
26+
// Extract value without verification
27+
const extractedValue = getSignedValue(signedValue) // 'user123'
2528
```
2629

2730
::: info
28-
The `unsign` helper accepts `undefined` or `null` as signed value and returns `undefined` for invalid inputs, enabling seamless handling of optional data.
31+
The `unsign` and `getSignedValue` helpers accept `undefined` or `null` as signed value and return `undefined` for invalid inputs, enabling seamless handling of optional data.
2932
:::

0 commit comments

Comments
 (0)