Skip to content

Commit a6dec3e

Browse files
authored
perf(standard-server): reduce payload size for batch responses (#354)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Refactor** - Enhanced batch response processing to ensure a consistent structure and improved asynchronous handling, including proper cleanup. - **Tests** - Updated validation criteria for response items to align with the refined response format. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 05d8f9b commit a6dec3e

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

packages/standard-server/src/batch/response.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { isAsyncIteratorObject } from '@orpc/shared'
33
import { parseBatchResponse, toBatchResponse } from './response'
44

55
describe('toBatchResponse & parseBatchResponse', () => {
6-
const r1: BatchResponseBodyItem = { index: 0, status: 200, headers: { 'x-custom': 'value1' }, body: 'test1' }
7-
const r2: BatchResponseBodyItem = { index: 1, status: 205, headers: { 'x-custom': 'value2' }, body: 'test2' }
6+
const r1: BatchResponseBodyItem = { index: 0, status: 200, headers: { }, body: 'test1' }
7+
const r2: BatchResponseBodyItem = { index: 1, status: 207, headers: { 'x-custom': 'value2' }, body: 'test2' }
88

99
it('success', async () => {
1010
const response = toBatchResponse({
@@ -45,7 +45,7 @@ describe('parseBatchResponse', () => {
4545
status: 207,
4646
headers: { 'x-custom': 'value' },
4747
body: (async function*() {
48-
yield 'invalid' as any
48+
yield { headers: {} } as any
4949
})(),
5050
}))
5151

packages/standard-server/src/batch/response.ts

+26-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { StandardResponse } from '../types'
1+
import type { StandardHeaders, StandardResponse } from '../types'
22
import { isAsyncIteratorObject, isObject } from '@orpc/shared'
33

44
export interface BatchResponseBodyItem extends StandardResponse {
@@ -10,7 +10,24 @@ export interface ToBatchResponseOptions extends StandardResponse {
1010
}
1111

1212
export function toBatchResponse(options: ToBatchResponseOptions): StandardResponse {
13-
return options
13+
return {
14+
...options,
15+
body: (async function* () {
16+
try {
17+
for await (const item of options.body) {
18+
yield {
19+
index: item.index,
20+
status: item.status === options.status ? undefined : item.status,
21+
headers: Object.keys(item.headers).length ? item.headers : undefined,
22+
body: item.body,
23+
} satisfies Partial<BatchResponseBodyItem>
24+
}
25+
}
26+
finally {
27+
options.body.return?.()
28+
}
29+
})(),
30+
}
1431
}
1532

1633
export function parseBatchResponse(response: StandardResponse): AsyncGenerator<BatchResponseBodyItem> {
@@ -25,13 +42,18 @@ export function parseBatchResponse(response: StandardResponse): AsyncGenerator<B
2542
return (async function* () {
2643
try {
2744
for await (const item of body) {
28-
if (!isObject(item) || !('index' in item) || !('status' in item) || !('headers' in item)) {
45+
if (!isObject(item) || !('index' in item) || typeof item.index !== 'number') {
2946
throw new TypeError('Invalid batch response', {
3047
cause: item,
3148
})
3249
}
3350

34-
yield item as unknown as BatchResponseBodyItem
51+
yield {
52+
index: item.index as number,
53+
status: item.status as undefined | number ?? response.status,
54+
headers: item.headers as undefined | StandardHeaders ?? {},
55+
body: item.body,
56+
} satisfies BatchResponseBodyItem
3557
}
3658
}
3759
finally {

0 commit comments

Comments
 (0)