@@ -22,7 +22,7 @@ export function snapshot(value, skip_warning = false) {
2222 /** @type {string[] } */
2323 const paths = [ ] ;
2424
25- const copy = clone ( value , new Map ( ) , '' , paths ) ;
25+ const copy = clone ( value , new Map ( ) , null , '' , paths ) ;
2626 if ( paths . length === 1 && paths [ 0 ] === '' ) {
2727 // value could not be cloned
2828 w . state_snapshot_uncloneable ( ) ;
@@ -40,18 +40,19 @@ export function snapshot(value, skip_warning = false) {
4040 return copy ;
4141 }
4242
43- return clone ( value , new Map ( ) , '' , empty ) ;
43+ return clone ( value , new Map ( ) , null , '' , empty ) ;
4444}
4545
4646/**
4747 * @template T
4848 * @param {T } value
4949 * @param {Map<T, Snapshot<T>> } cloned
50+ * @param {null | T } json_instance
5051 * @param {string } path
5152 * @param {string[] } paths
5253 * @returns {Snapshot<T> }
5354 */
54- function clone ( value , cloned , path , paths ) {
55+ function clone ( value , cloned , json_instance , path , paths ) {
5556 if ( typeof value === 'object' && value !== null ) {
5657 const unwrapped = cloned . get ( value ) ;
5758 if ( unwrapped !== undefined ) return unwrapped ;
@@ -62,13 +63,12 @@ function clone(value, cloned, path, paths) {
6263 if ( is_array ( value ) ) {
6364 const copy = /** @type {Snapshot<any> } */ ( [ ] ) ;
6465 cloned . set ( value , copy ) ;
66+ if ( json_instance !== null ) {
67+ cloned . set ( json_instance , copy ) ;
68+ }
6569
6670 for ( let i = 0 ; i < value . length ; i += 1 ) {
67- var element = value [ i ] ;
68- if ( cloned . get ( element ) === null ) {
69- cloned . set ( element , copy ) ;
70- }
71- copy . push ( clone ( element , cloned , DEV ? `${ path } [${ i } ]` : path , paths ) ) ;
71+ copy . push ( clone ( value [ i ] , cloned , null , DEV ? `${ path } [${ i } ]` : path , paths ) ) ;
7272 }
7373
7474 return copy ;
@@ -78,13 +78,13 @@ function clone(value, cloned, path, paths) {
7878 /** @type {Snapshot<any> } */
7979 const copy = { } ;
8080 cloned . set ( value , copy ) ;
81+ if ( json_instance !== null ) {
82+ cloned . set ( json_instance , copy ) ;
83+ }
8184
8285 for ( var key in value ) {
83- var prop = /** @type {any } */ ( value [ key ] ) ;
84- if ( cloned . get ( prop ) === null ) {
85- cloned . set ( prop , copy ) ;
86- }
87- copy [ key ] = clone ( prop , cloned , DEV ? `${ path } .${ key } ` : path , paths ) ;
86+ // @ts -ignore
87+ copy [ key ] = clone ( value [ key ] , cloned , null , DEV ? `${ path } .${ key } ` : path , paths ) ;
8888 }
8989
9090 return copy ;
@@ -95,13 +95,12 @@ function clone(value, cloned, path, paths) {
9595 }
9696
9797 if ( typeof ( /** @type {T & { toJSON?: any } } */ ( value ) . toJSON ) === 'function' ) {
98- // To avoid cycles set the clone to null, so if we encounter it again later we can
99- // slot in the currently copied object instead
100- // @ts -ignore
101- cloned . set ( value , null ) ;
98+ // Associate the instance with the toJSON clone
99+ var ref_json_instance = value ;
102100 return clone (
103101 /** @type {T & { toJSON(): any } } */ ( value ) . toJSON ( ) ,
104102 cloned ,
103+ ref_json_instance ,
105104 DEV ? `${ path } .toJSON()` : path ,
106105 paths
107106 ) ;
0 commit comments