11import { escape } from "./escape.js" ;
2- import { StringifyOptions , isYSONStringifiable , keyRegex } from "./types.js" ;
2+ import { StringifyOptions , TypedArray , isYSONStringifiable , keyRegex } from "./types.js" ;
33
44export function stringifyValue ( value : unknown , options : StringifyOptions , depth : number ) : string | undefined {
55 switch ( typeof value ) {
@@ -32,35 +32,13 @@ export function stringifyValue(value: unknown, options: StringifyOptions, depth:
3232 }
3333
3434 if ( Array . isArray ( value ) ) return stringifyArray ( value , options , depth )
35- if ( value instanceof Map ) {
36- const newValue = Object . fromEntries ( value . entries ( ) )
37- const raw = stringifyObject ( newValue , options , depth )
38- return `Map${ options . spaceAfterPunctuation ? " " : "" } ${ raw } `
39- }
40- if ( value instanceof Set ) {
41- const newValue = Array . from ( value . values ( ) )
42- const raw = stringifyArray ( newValue , options , depth )
43- return `Set${ options . spaceAfterPunctuation ? " " : "" } ${ raw } `
44- }
45- if ( value instanceof Date ) {
46- const newValue = value . toISOString ( )
47- const raw = escape ( newValue )
48- return `Date${ options . spaceAfterPunctuation ? " " : "" } ${ raw } `
49- }
50- if ( value instanceof URL ) {
51- const newValue = value . href
52- const raw = escape ( newValue )
53- return `URL${ options . spaceAfterPunctuation ? " " : "" } ${ raw } `
54- }
55- if ( ArrayBuffer . isView ( value ) || value instanceof ArrayBuffer ) {
56- const type = value . constructor . name
57- if ( value instanceof DataView ) value = value . buffer
58- if ( value instanceof ArrayBuffer ) value = new Uint8Array ( value )
59- const raw = stringifyArray ( Array . from ( value as [ ] ) , options , depth )
60- return `${ type } ${ options . spaceAfterPunctuation ? " " : "" } ${ raw } `
35+
36+ let stringified = stringifyBuiltin ( value , options , depth )
37+ if ( stringified == null ) {
38+ stringified = stringifyObject ( value as Record < string , unknown > , options , depth )
6139 }
6240
63- return stringifyObject ( value as Record < string , unknown > , options , depth )
41+ return stringified
6442 }
6543
6644 return undefined
@@ -105,4 +83,61 @@ function joinValues(arr: unknown[], open: string, close: string, options: String
10583 if ( options . insetSpace ) return `${ open } ${ arr . join ( separator ) } ${ close } `
10684 return `${ open } ${ arr . join ( separator ) } ${ close } `
10785 }
86+ }
87+
88+ function stringifyBuiltin ( value : object , options : StringifyOptions , depth : number ) : string | null {
89+ let result : { raw : string , type : string } | null = null
90+
91+ if ( value instanceof Map ) result = stringifyMap ( value , options , depth )
92+ if ( value instanceof Set ) result = stringifySet ( value , options , depth )
93+ if ( value instanceof Date ) result = stringifyDate ( value )
94+ if ( value instanceof URL ) result = stringifyURL ( value )
95+ if ( ArrayBuffer . isView ( value ) || value instanceof ArrayBuffer ) {
96+ result = stringifyArrayBufferLike ( value , options , depth )
97+ }
98+
99+ if ( result ) {
100+ return `${ result . type } ${ options . spaceAfterPunctuation ? " " : "" } ${ result . raw } `
101+ }
102+
103+ return null
104+ }
105+
106+ function stringifyMap ( map : Map < string , unknown > , options : StringifyOptions , depth : number ) {
107+ const obj = Object . fromEntries ( map . entries ( ) )
108+ const raw = stringifyObject ( obj , options , depth )
109+
110+ return { raw, type : "Map" }
111+ }
112+
113+ function stringifySet ( set : Set < unknown > , options : StringifyOptions , depth : number ) {
114+ const arr = Array . from ( set . values ( ) )
115+ const raw = stringifyArray ( arr , options , depth )
116+
117+ return { raw, type : "Set" }
118+ }
119+
120+ function stringifyDate ( date : Date ) {
121+ const raw = escape ( date . toISOString ( ) )
122+
123+ return { raw, type : "Date" }
124+ }
125+
126+ function stringifyURL ( url : URL ) {
127+ const raw = escape ( url . href )
128+
129+ return { raw, type : "URL" }
130+ }
131+
132+ function stringifyArrayBufferLike ( buffer : ArrayBuffer | ArrayBufferView < ArrayBufferLike > , options : StringifyOptions , depth : number ) {
133+ const type = buffer . constructor . name
134+ let arr : ( number | bigint ) [ ]
135+
136+ if ( buffer instanceof DataView ) arr = Array . from ( new Uint8Array ( buffer . buffer , buffer . byteOffset , buffer . byteLength ) )
137+ else if ( buffer instanceof ArrayBuffer ) arr = Array . from ( new Uint8Array ( buffer ) )
138+ else arr = Array . from ( buffer as unknown as Iterable < number | bigint > )
139+
140+ const raw = stringifyArray ( arr , options , depth )
141+
142+ return { raw, type }
108143}
0 commit comments