File tree Expand file tree Collapse file tree 2 files changed +48
-1
lines changed Expand file tree Collapse file tree 2 files changed +48
-1
lines changed Original file line number Diff line number Diff line change @@ -7,6 +7,10 @@ import type { ExtData } from "./ExtData";
77export const DEFAULT_MAX_DEPTH = 100 ;
88export const DEFAULT_INITIAL_BUFFER_SIZE = 2048 ;
99
10+ const hastoJSON = ( value : unknown ) : value is { toJSON : unknown } => {
11+ return typeof value === 'object' && value !== null && 'toJSON' in value ;
12+ } ;
13+
1014export class Encoder < ContextType = undefined > {
1115 private pos = 0 ;
1216 private view = new DataView ( new ArrayBuffer ( this . initialBufferSize ) ) ;
@@ -194,7 +198,11 @@ export class Encoder<ContextType = undefined> {
194198 } else if ( ArrayBuffer . isView ( object ) ) {
195199 this . encodeBinary ( object ) ;
196200 } else if ( typeof object === "object" ) {
197- this . encodeMap ( object as Record < string , unknown > , depth ) ;
201+ if ( hastoJSON ( object ) && typeof object . toJSON === "function" ) {
202+ this . doEncode ( object . toJSON ( ) , depth ) ;
203+ } else {
204+ this . encodeMap ( object as Record < string , unknown > , depth ) ;
205+ }
198206 } else {
199207 // symbol, function and other special object come here unless extensionCodec handles them.
200208 throw new Error ( `Unrecognized object: ${ Object . prototype . toString . apply ( object ) } ` ) ;
Original file line number Diff line number Diff line change @@ -120,4 +120,43 @@ describe("decodeAsync", () => {
120120 const object = await decodeAsync ( createStream ( ) ) ;
121121 assert . deepStrictEqual ( object , { "foo" : "bar" } ) ;
122122 } ) ;
123+
124+ it ( "decodes objects with toJSON methods" , async ( ) => {
125+ const object = {
126+ string : "Hello, world!" ,
127+ nested : {
128+ int : - 45 ,
129+ json : {
130+ toJSON ( ) {
131+ return {
132+ float : Math . PI ,
133+ int64 : Number . MIN_SAFE_INTEGER ,
134+ timestamp : new Date ( 0 ) ,
135+ custom : {
136+ toJSON : ( ) => "custom"
137+ }
138+ }
139+ }
140+ }
141+ }
142+ } ;
143+
144+ const createStream = async function * ( ) {
145+ for ( const byte of encode ( object ) ) {
146+ yield [ byte ] ;
147+ }
148+ } ;
149+ assert . deepStrictEqual ( await decodeAsync ( createStream ( ) ) , {
150+ string : "Hello, world!" ,
151+ nested : {
152+ int : - 45 ,
153+ json : {
154+ float : Math . PI ,
155+ int64 : Number . MIN_SAFE_INTEGER ,
156+ timestamp : new Date ( 0 ) ,
157+ custom : "custom"
158+ }
159+ }
160+ } ) ;
161+ } ) ;
123162} ) ;
You can’t perform that action at this time.
0 commit comments