Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Too much recursion error with self reference in class instance with toJSON #14336

Closed
tkvw opened this issue Nov 17, 2024 · 2 comments · Fixed by #14347
Closed

Too much recursion error with self reference in class instance with toJSON #14336

tkvw opened this issue Nov 17, 2024 · 2 comments · Fixed by #14347
Assignees
Labels

Comments

@tkvw
Copy link

tkvw commented Nov 17, 2024

Describe the bug

When using $inspect on a $state with a class instance with toJSON(), which returns a self reference, the creation of a snapshot will end in a recursion error.

I am wondering if the creation of a snapshot is needed at all if $state.raw is used.

For what is worth: I ran into this issue using a snapshot state of a xstate actor in a $state.raw rune.

Reproduction

Very minimal example is:

https://svelte.dev/playground/c610857749e347dcad7dbb7af287b74e?version=5.2.1

Logs

No response

System Info

Not relevant

Severity

annoyance

@trueadm
Copy link
Contributor

trueadm commented Nov 17, 2024

This is a tricky one, as toJSON is a standard JS function for JSON serialisation and one of the constraints of it is that it can't self reference. Ignoring Svelte, if you do JSON.stringify(new A()) on your class, you'll get the same issue.

Maybe we can do something with $state.snapshot, which inspect is using under the hood to avoid this, but I wonder if diverging from how toJSON works is going to cause bigger issues.

@tkvw
Copy link
Author

tkvw commented Nov 18, 2024

I think there's something more going on, I've tried a simple example using xstate:

<script lang="ts">
  import { createActor, setup } from "xstate";

  const machine = setup({}).createMachine({});
  const actor = createActor(machine, {}).start();

  const snapshot = actor.getSnapshot();
  // This simply prints a JSON object to the console 
  console.log(JSON.stringify(snapshot, null, 2));
  
  const state = $state(snapshot); // or const state = $state.raw(snapshot);
  // This fails with a recursion error 
  $inspect(state);
</script>

Gives:

 RangeError: Maximum call stack size exceeded

	in +page.svelte
	in +layout.svelte
	in root.svelte

    at clone (chunk-MSQQWQWT.js?v=38f3bf79:318:15)
    at clone (chunk-MSQQWQWT.js?v=38f3bf79:345:21)
    at clone (chunk-MSQQWQWT.js?v=38f3bf79:357:14) 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants