Skip to content

Commit 371be67

Browse files
authored
feat(client)!: update onEventIteratorStatusChange (#212)
1 parent 2546825 commit 371be67

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,34 @@ catch (error) {
7070
::: info
7171
Errors thrown by the server can be instances of `ORPCError`.
7272
:::
73+
74+
## Event Iterator Connection Status
75+
76+
Combine with `onEventIteratorStatusChange` to track the connection status of the event iterator.
77+
78+
```ts twoslash
79+
declare const client: { streaming: () => Promise<AsyncGenerator<{ message: string }, void, void>> }
80+
// ---cut---
81+
import { onEventIteratorStatusChange } from '@orpc/client'
82+
83+
let status: 'connecting' | 'error' | 'reconnecting' | 'connected' | 'closed' = 'connecting'
84+
let unsubscribe: (() => void) | undefined
85+
86+
try {
87+
const iterator = await client.streaming()
88+
89+
unsubscribe = onEventIteratorStatusChange(iterator, (newStatus) => {
90+
status = newStatus
91+
})
92+
93+
for await (const event of iterator) {
94+
console.log(event.message)
95+
}
96+
}
97+
catch (error) {
98+
status = 'error'
99+
}
100+
finally {
101+
unsubscribe?.()
102+
}
103+
```

packages/client/src/event-iterator-state.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,29 @@ describe('eventIterator Status Management', () => {
2323

2424
it('invokes the callback immediately if notifyImmediately is true', () => {
2525
const callback = vi.fn()
26-
onEventIteratorStatusChange(dummyIterator, callback, true)
26+
onEventIteratorStatusChange(dummyIterator, callback, { notifyImmediately: true })
2727
// The callback should be called right away with the current status.
2828
expect(callback).toHaveBeenCalledWith('connected')
2929
})
3030

3131
it('does not invoke the callback immediately if notifyImmediately is false', () => {
3232
const callback = vi.fn()
33-
onEventIteratorStatusChange(dummyIterator, callback, false)
33+
onEventIteratorStatusChange(dummyIterator, callback, { notifyImmediately: false })
3434
// Since immediate notification is disabled, the callback should not have been called.
3535
expect(callback).not.toHaveBeenCalled()
3636
})
3737

3838
it('calls the callback when the status is updated', () => {
3939
const callback = vi.fn()
40-
onEventIteratorStatusChange(dummyIterator, callback, false)
40+
onEventIteratorStatusChange(dummyIterator, callback, { notifyImmediately: false })
4141
updateEventIteratorStatus(initialState, 'reconnecting')
4242
// The callback should be called with the new status.
4343
expect(callback).toHaveBeenCalledWith('reconnecting')
4444
})
4545

4646
it('does not call the callback if the status is updated to the same value', () => {
4747
const callback = vi.fn()
48-
onEventIteratorStatusChange(dummyIterator, callback, false)
48+
onEventIteratorStatusChange(dummyIterator, callback, { notifyImmediately: false })
4949
// Update with the same status as the initial one.
5050
updateEventIteratorStatus(initialState, 'connected')
5151
// The callback should not be triggered.
@@ -54,7 +54,7 @@ describe('eventIterator Status Management', () => {
5454

5555
it('removes the listener when unsubscribed', () => {
5656
const callback = vi.fn()
57-
const unsubscribe = onEventIteratorStatusChange(dummyIterator, callback, false)
57+
const unsubscribe = onEventIteratorStatusChange(dummyIterator, callback, { notifyImmediately: false })
5858
// Update status to trigger the callback.
5959
updateEventIteratorStatus(initialState, 'reconnecting')
6060
expect(callback).toHaveBeenCalledTimes(1)

packages/client/src/event-iterator-state.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ export function updateEventIteratorStatus(
2727
export function onEventIteratorStatusChange(
2828
iterator: AsyncIteratorObject<unknown, unknown, void>,
2929
callback: (status: ConnectionStatus) => void,
30-
notifyImmediately = true,
30+
options: { notifyImmediately?: boolean } = {},
3131
): () => void {
32+
const notifyImmediately = options.notifyImmediately ?? true
33+
3234
const state = iteratorStates.get(iterator)
3335

3436
if (!state) {

0 commit comments

Comments
 (0)