@@ -15,9 +15,10 @@ const empty = [];
1515 * @template T
1616 * @param {T } value
1717 * @param {boolean } [skip_warning]
18+ * @param {boolean } [only_deproxy]
1819 * @returns {Snapshot<T> }
1920 */
20- export function snapshot ( value , skip_warning = false ) {
21+ export function snapshot ( value , skip_warning = false , only_deproxy = false ) {
2122 if ( DEV && ! skip_warning ) {
2223 /** @type {string[] } */
2324 const paths = [ ] ;
@@ -40,7 +41,7 @@ export function snapshot(value, skip_warning = false) {
4041 return copy ;
4142 }
4243
43- return clone ( value , new Map ( ) , '' , empty ) ;
44+ return clone ( value , new Map ( ) , '' , empty , null , only_deproxy ) ;
4445}
4546
4647/**
@@ -49,16 +50,19 @@ export function snapshot(value, skip_warning = false) {
4950 * @param {Map<T, Snapshot<T>> } cloned
5051 * @param {string } path
5152 * @param {string[] } paths
52- * @param {null | T } original The original value, if `value` was produced from a `toJSON` call
53+ * @param {null | T } [original] The original value, if `value` was produced from a `toJSON` call
54+ * @param {boolean } [only_deproxy] Don't clone objects that aren't proxies
5355 * @returns {Snapshot<T> }
5456 */
55- function clone ( value , cloned , path , paths , original = null ) {
57+ function clone ( value , cloned , path , paths , original = null , only_deproxy = false ) {
5658 if ( typeof value === 'object' && value !== null ) {
5759 var unwrapped = cloned . get ( value ) ;
5860 if ( unwrapped !== undefined ) return unwrapped ;
5961
60- if ( value instanceof Map ) return /** @type {Snapshot<T> } */ ( new Map ( value ) ) ;
61- if ( value instanceof Set ) return /** @type {Snapshot<T> } */ ( new Set ( value ) ) ;
62+ if ( value instanceof Map )
63+ return /** @type {Snapshot<T> } */ ( only_deproxy ? value : new Map ( value ) ) ;
64+ if ( value instanceof Set )
65+ return /** @type {Snapshot<T> } */ ( only_deproxy ? value : new Set ( value ) ) ;
6266
6367 if ( is_array ( value ) ) {
6468 var copy = /** @type {Snapshot<any> } */ ( Array ( value . length ) ) ;
@@ -71,7 +75,7 @@ function clone(value, cloned, path, paths, original = null) {
7175 for ( var i = 0 ; i < value . length ; i += 1 ) {
7276 var element = value [ i ] ;
7377 if ( i in value ) {
74- copy [ i ] = clone ( element , cloned , DEV ? `${ path } [${ i } ]` : path , paths ) ;
78+ copy [ i ] = clone ( element , cloned , DEV ? `${ path } [${ i } ]` : path , paths , null , only_deproxy ) ;
7579 }
7680 }
7781
@@ -88,26 +92,49 @@ function clone(value, cloned, path, paths, original = null) {
8892 }
8993
9094 for ( var key in value ) {
91- // @ts -expect-error
92- copy [ key ] = clone ( value [ key ] , cloned , DEV ? `${ path } .${ key } ` : path , paths ) ;
95+ copy [ key ] = clone (
96+ // @ts -expect-error
97+ value [ key ] ,
98+ cloned ,
99+ DEV ? `${ path } .${ key } ` : path ,
100+ paths ,
101+ null ,
102+ only_deproxy
103+ ) ;
93104 }
94105
95106 return copy ;
96107 }
97108
98109 if ( value instanceof Date ) {
99- return /** @type {Snapshot<T> } */ ( structuredClone ( value ) ) ;
110+ if ( only_deproxy ) {
111+ structuredClone ( value ) ;
112+ } else {
113+ return /** @type {Snapshot<T> } */ ( structuredClone ( value ) ) ;
114+ }
100115 }
101116
102117 if ( typeof ( /** @type {T & { toJSON?: any } } */ ( value ) . toJSON ) === 'function' ) {
103- return clone (
104- /** @type {T & { toJSON(): any } } */ ( value ) . toJSON ( ) ,
105- cloned ,
106- DEV ? `${ path } .toJSON()` : path ,
107- paths ,
108- // Associate the instance with the toJSON clone
109- value
110- ) ;
118+ if ( ! only_deproxy ) {
119+ return clone (
120+ /** @type {T & { toJSON(): any } } */ ( value ) . toJSON ( ) ,
121+ cloned ,
122+ DEV ? `${ path } .toJSON()` : path ,
123+ paths ,
124+ // Associate the instance with the toJSON clone
125+ value
126+ ) ;
127+ } else {
128+ // we still want to read each property
129+ clone (
130+ /** @type {T & { toJSON(): any } } */ ( value ) . toJSON ( ) ,
131+ cloned ,
132+ DEV ? `${ path } .toJSON()` : path ,
133+ paths ,
134+ // Associate the instance with the toJSON clone
135+ value
136+ ) ;
137+ }
111138 }
112139 }
113140
@@ -116,6 +143,13 @@ function clone(value, cloned, path, paths, original = null) {
116143 return /** @type {Snapshot<T> } */ ( value ) ;
117144 }
118145
146+ if ( only_deproxy ) {
147+ try {
148+ structuredClone ( value ) ;
149+ } catch { }
150+ return /** @type {Snapshot<T> } */ ( value ) ;
151+ }
152+
119153 try {
120154 return /** @type {Snapshot<T> } */ ( structuredClone ( value ) ) ;
121155 } catch ( e ) {
0 commit comments