Skip to content

Commit 89acf15

Browse files
authored
fix: serialize undefined array elements as null (#1505)
Fixes #1504 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed JSON serialization handling of undefined values in arrays to ensure proper round-trip serialization and deserialization. * **Tests** * Added comprehensive test coverage for undefined array element handling, including nested cases. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 8d90c8f commit 89acf15

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

packages/client/src/adapters/standard/rpc-json-serializer.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,30 @@ describe.each([
136136
})
137137
})
138138

139+
describe('standardRPCJsonSerializer: undefined in arrays produces JSON-safe output', () => {
140+
const serializer = new StandardRPCJsonSerializer()
141+
142+
it('serialize uses null as placeholder for undefined array elements', () => {
143+
const [json] = serializer.serialize([undefined, 'a', undefined])
144+
expect(json).toEqual([null, 'a', null])
145+
})
146+
147+
it('round-trips undefined array elements through JSON.parse(JSON.stringify(...))', () => {
148+
const [json, meta, maps, blobs] = serializer.serialize([undefined, 'a', undefined])
149+
const result = JSON.parse(JSON.stringify({ json, meta, maps }))
150+
const deserialized = serializer.deserialize(result.json, result.meta, result.maps, (i: number) => blobs[i]!)
151+
expect(deserialized).toEqual([undefined, 'a', undefined])
152+
})
153+
154+
it('round-trips nested undefined array elements (e.g. TanStack Query pageParams)', () => {
155+
const data = { pageParams: [undefined, 'cursor_abc'], pages: [{ items: [1, 2] }] }
156+
const [json, meta, maps, blobs] = serializer.serialize(data)
157+
const result = JSON.parse(JSON.stringify({ json, meta, maps }))
158+
const deserialized = serializer.deserialize(result.json, result.meta, result.maps, (i: number) => blobs[i]!)
159+
expect(deserialized).toEqual(data)
160+
})
161+
})
162+
139163
describe('standardRPCJsonSerializer: custom serializers', () => {
140164
it('should throw when type is duplicated', () => {
141165
expect(() => {

packages/client/src/adapters/standard/rpc-json-serializer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export class StandardRPCJsonSerializer {
100100
const json = data.map((v, i) => {
101101
if (v === undefined) {
102102
meta.push([STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES.UNDEFINED, ...segments, i])
103-
return v
103+
return null
104104
}
105105

106106
return this.serialize(v, [...segments, i], meta, maps, blobs)[0]

0 commit comments

Comments
 (0)