fix: avoid recursion error when tagging circular references (#16622)

* fix: avoid recursion error when tagging circular references

* try suggestion

* add some logging

* make logging clearer

* more

* try this

* add test

* tweak

* fix?

* fix??
pull/16630/head
ComputerGuy 1 month ago committed by GitHub
parent ad19a1a0f5
commit a543559acf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: avoid recursion error when tagging circular references

@ -93,9 +93,11 @@ export function proxy(value) {
/** Used in dev for $inspect.trace() */
var path = '';
let updating = false;
/** @param {string} new_path */
function update_path(new_path) {
if (updating) return;
updating = true;
path = new_path;
tag(version, `${path} version`);
@ -104,6 +106,7 @@ export function proxy(value) {
for (const [prop, source] of sources) {
tag(source, get_label(path, prop));
}
updating = false;
}
return new Proxy(/** @type {any} */ (value), {
@ -284,13 +287,13 @@ export function proxy(value) {
if (s === undefined) {
if (!has || get_descriptor(target, prop)?.writable) {
s = with_parent(() => source(undefined, stack));
set(s, proxy(value));
sources.set(prop, s);
if (DEV) {
tag(s, get_label(path, prop));
}
set(s, proxy(value));
sources.set(prop, s);
}
} else {
has = s.v !== UNINITIALIZED;

@ -0,0 +1,26 @@
import { test } from '../../test';
import { normalise_trace_logs } from '../../../helpers.js';
export default test({
compileOptions: {
dev: true
},
test({ assert, logs }) {
const files = { id: 1, items: [{ id: 2, items: [{ id: 3 }, { id: 4 }] }] };
// @ts-expect-error
files.items[0].parent = files;
assert.deepEqual(normalise_trace_logs(logs), [
{ log: 'test (main.svelte:5:4)' },
{ log: '$state', highlighted: true },
{ log: 'filesState.files', highlighted: false },
{ log: files },
{ log: '$state', highlighted: true },
{ log: 'filesState.files.items[0].parent.items', highlighted: false },
{ log: files.items },
{ log: '$state', highlighted: true },
{ log: 'filesState.files.items[0].parent.items[0]', highlighted: false },
{ log: files.items[0] }
]);
}
});

@ -0,0 +1,10 @@
<script>
const filesState = $state({ files: {} });
let nodes = { id: 1, items: [{ id: 2, items: [{ id: 3 }, { id: 4 }] }] };
filesState.files = nodes;
function test() {
$inspect.trace();
filesState.files.items[0].parent = filesState.files;
}
$effect(test);
</script>
Loading…
Cancel
Save