Skip to content

Commit 1d9ebd5

Browse files
committed
better fixc
1 parent 546a829 commit 1d9ebd5

File tree

3 files changed

+38
-19
lines changed

3 files changed

+38
-19
lines changed

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

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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
);

packages/svelte/tests/runtime-runes/samples/inspect-recursive-2/_config.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,17 @@ export default test({
77

88
async test({ assert, logs }) {
99
var a = {
10-
a: null
10+
a: {}
1111
};
1212
a.a = a;
13-
assert.deepEqual(logs, ['init', { a }]);
13+
14+
var b = {
15+
a: {
16+
b: {}
17+
}
18+
};
19+
b.a.b = b;
20+
21+
assert.deepEqual(logs, ['init', a, 'init', b]);
1422
}
1523
});

packages/svelte/tests/runtime-runes/samples/inspect-recursive-2/main.svelte

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,16 @@
88
}
99
const state = $state(new A());
1010
$inspect(state);
11+
12+
class B {
13+
toJSON(){
14+
return {
15+
a: {
16+
b: this
17+
}
18+
}
19+
}
20+
}
21+
const state2 = $state(new B());
22+
$inspect(state2);
1123
</script>

0 commit comments

Comments
 (0)