Skip to content

Commit ad19a1a

Browse files
authored
fix: don't clone non-proxies in $inspect (#16617)
* fix: don't clone non-proxies in `$inspect` * apply suggestion * lint
1 parent 2e02868 commit ad19a1a

File tree

2 files changed

+23
-9
lines changed

2 files changed

+23
-9
lines changed

.changeset/itchy-games-guess.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: don't clone non-proxies in `$inspect`

packages/svelte/src/internal/shared/clone.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ const empty = [];
1515
* @template T
1616
* @param {T} value
1717
* @param {boolean} [skip_warning]
18+
* @param {boolean} [no_tojson]
1819
* @returns {Snapshot<T>}
1920
*/
20-
export function snapshot(value, skip_warning = false) {
21+
export function snapshot(value, skip_warning = false, no_tojson = false) {
2122
if (DEV && !skip_warning) {
2223
/** @type {string[]} */
2324
const paths = [];
2425

25-
const copy = clone(value, new Map(), '', paths);
26+
const copy = clone(value, new Map(), '', paths, null, no_tojson);
2627
if (paths.length === 1 && paths[0] === '') {
2728
// value could not be cloned
2829
w.state_snapshot_uncloneable();
@@ -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, no_tojson);
4445
}
4546

4647
/**
@@ -49,10 +50,11 @@ 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} [no_tojson]
5355
* @returns {Snapshot<T>}
5456
*/
55-
function clone(value, cloned, path, paths, original = null) {
57+
function clone(value, cloned, path, paths, original = null, no_tojson = false) {
5658
if (typeof value === 'object' && value !== null) {
5759
var unwrapped = cloned.get(value);
5860
if (unwrapped !== undefined) return unwrapped;
@@ -71,7 +73,7 @@ function clone(value, cloned, path, paths, original = null) {
7173
for (var i = 0; i < value.length; i += 1) {
7274
var element = value[i];
7375
if (i in value) {
74-
copy[i] = clone(element, cloned, DEV ? `${path}[${i}]` : path, paths);
76+
copy[i] = clone(element, cloned, DEV ? `${path}[${i}]` : path, paths, null, no_tojson);
7577
}
7678
}
7779

@@ -88,8 +90,15 @@ function clone(value, cloned, path, paths, original = null) {
8890
}
8991

9092
for (var key in value) {
91-
// @ts-expect-error
92-
copy[key] = clone(value[key], cloned, DEV ? `${path}.${key}` : path, paths);
93+
copy[key] = clone(
94+
// @ts-expect-error
95+
value[key],
96+
cloned,
97+
DEV ? `${path}.${key}` : path,
98+
paths,
99+
null,
100+
no_tojson
101+
);
93102
}
94103

95104
return copy;
@@ -99,7 +108,7 @@ function clone(value, cloned, path, paths, original = null) {
99108
return /** @type {Snapshot<T>} */ (structuredClone(value));
100109
}
101110

102-
if (typeof (/** @type {T & { toJSON?: any } } */ (value).toJSON) === 'function') {
111+
if (typeof (/** @type {T & { toJSON?: any } } */ (value).toJSON) === 'function' && !no_tojson) {
103112
return clone(
104113
/** @type {T & { toJSON(): any } } */ (value).toJSON(),
105114
cloned,

0 commit comments

Comments
 (0)