1+ function isNativeObject ( value : object ) {
2+ return / ^ \[ o b j e c t .+ ?C o n s t r u c t o r ] $ / . test ( Object . prototype . toString . call ( value ) )
3+ }
4+
5+ export const classes : Map < string , Function > = new Map ( )
6+ export const deSerialize : Map < Function , { serialize ?: ( value ?: object ) => SerializableType , deserialize ?: ( value : SerializedType ) => object } > = new Map ( )
7+
8+ export type SerializedType =
9+ string
10+ | number
11+ | boolean
12+ | null
13+ | undefined
14+ | Array < SerializedType >
15+ | { [ k : string ] : SerializedType }
16+
17+ export type SerializableType =
18+ string
19+ | number
20+ | boolean
21+ | null
22+ | undefined
23+ | Function
24+ | Array < SerializableType >
25+ | { [ k : string ] : SerializableType }
26+ | Set < SerializableType >
27+ | Map < SerializableType , SerializableType >
28+
129export function serialize ( value : any ) : any | void {
230 // todo: handle other builtins
331 if ( [ 'string' , 'number' , 'boolean' ] . includes ( typeof value ) || ! value ) {
432 return value
5- } else if ( typeof value === 'function' ) {
6- return {
7- $$iposType : 'Function' ,
8- data : value . toString ( )
9- }
1033 } else if ( Array . isArray ( value ) ) {
1134 return value . map ( v => serialize ( v ) )
1235 } else if ( value . constructor === { } . constructor || value . valueOf ( ) . constructor === { } . constructor ) {
1336 return Object . fromEntries (
1437 Array . from ( Object . entries ( value ) )
1538 . map ( ( [ key , value ] ) => [ key , serialize ( value ) ] )
1639 )
40+ } else if ( typeof value === 'function' ) {
41+ return {
42+ $$iposType : 'Function' ,
43+ data : value . toString ( )
44+ }
1745 } else if ( value instanceof Set ) {
1846 return {
1947 $$iposType : 'Set' ,
@@ -28,12 +56,21 @@ export function serialize(value: any): any | void {
2856 . map ( ( [ key , value ] ) => [ key , serialize ( value ) ] )
2957 )
3058 }
59+ } else if ( isNativeObject ( value ) ) {
60+ throw new Error ( `Could not serialise: \`${ value . constructor . name } \`.` )
3161 } else {
32- if ( ! value . stringify && ! value . serialize )
62+ const serializeMethod = deSerialize . get ( value . constructor ) ?. serialize ?? value . stringify ?? value . serialize
63+ if ( ! serializeMethod )
3364 throw new Error (
3465 `Class: \`${ value . constructor . name } \` must have methods to serialize and deserialize objects. (\`.stringify()\`, \`.serialize()\`)`
3566 )
36- // return value.toString()
67+
68+ return {
69+ $$iposType : value . constructor . name ,
70+ data : serialize (
71+ serializeMethod . call ( value , value )
72+ )
73+ }
3774 }
3875}
3976
@@ -64,6 +101,17 @@ export function deserialize(value: string | number | Array<any> | { $$iposType?:
64101 Array . from ( Object . entries ( value . data ) )
65102 . map ( deserialize )
66103 )
104+ } else if ( classes . has ( value . $$iposType ) ) {
105+ const constructor = classes . get ( value . $$iposType ) as Function
106+ const deserializeMethod = deSerialize . get ( constructor ) ?. deserialize ??
107+ ( constructor as unknown as { from : Function } ) ?. from
108+
109+ if ( ! deserializeMethod )
110+ throw new Error ( `Did not recognize type \`${ value . $$iposType } \`. Did you register it in the child process?` )
111+
112+ return deserializeMethod ( deserialize ( value . data ) )
113+ } else {
114+ throw new Error ( `Did not recognize type \`${ value . $$iposType } \`. Did you register it in the child process?` )
67115 }
68116 } else
69117 console . warn ( 'I don\'t know' , value )
0 commit comments