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

Breaks superforms internal sate restore on soft-reload, and on hard-reload with snapshots enabled #205

Open
Mardoxx opened this issue Dec 14, 2024 · 12 comments

Comments

@Mardoxx
Copy link

Mardoxx commented Dec 14, 2024

Describe the bug

Superforms internal state is not being restored when using snapshots, and also not restored on soft refresh.

  1. Superforms state not restored when soft refreshing.

    • This behaviour is with and without snapshots
  2. Superforms state not restored when soft or hard refreshing.

    • This is behaviour is with snapshots

Existing behaviour:

clone https://github.com/ciscoheat/superforms-examples/tree/tutorial-valibot (currently at 2414332)

  1. Add <SuperDebug data={$formData} /> to the bottom of the page

  2. pnpm upgrade (or whatever package manager)

  3. Run the project

  4. Enter something in the email field

  5. Soft refresh with cmd+r

  6. Data is restored in superforms state

  7. Hard refresh (cmd+shift+r)

  8. State is (correctly) reset

Enable snapshots
export const snapshot = { capture, restore };

Do the same with hard refresh, state is restored.

Reproduction

Install formsnap
pnpm upgrade or whatever to get version numbers in line with my environment below

<script lang="ts">
	import SuperDebug, { superForm } from 'sveltekit-superforms';
	import type { PageData } from './$types';
	import { valibot } from 'sveltekit-superforms/adapters';
	import { schema } from './schema';
	import { Control, Description, Field, FieldErrors, Label } from 'formsnap';

	export let data: PageData;

	const form = superForm(data.form, {
		validators: valibot(schema)
	});

	const { form: formData, errors, constraints, message, enhance, capture, restore } = form;

	//export const snapshot = { capture, restore };
</script>

{#if $message}<h3>{$message}</h3>{/if}

<form method="POST" use:enhance>
	<Field {form} name="name">
		<Control>
			{#snippet children({ props })}
				<Label>Name</Label>
				<input {...props} type="test" bind:value={$formData.name} />
			{/snippet}
		</Control>
		<Description>Use your company email if you have one.</Description>
		<FieldErrors />
	</Field>

	<Field {form} name="email">
		<Control>
			{#snippet children({ props })}
				<Label>Email</Label>
				<input {...props} type="test" bind:value={$formData.email} />
			{/snippet}
		</Control>
		<Description>Use your company email if you have one.</Description>
		<FieldErrors />
	</Field>

	<div><button>Submit</button></div>
</form>

<hr />
<p>
	💥 <a target="_blank" href="https://superforms.rocks">Created with Superforms for SvelteKit</a> 💥
</p>
<SuperDebug data={$formData} />

<style>
	.invalid {
		color: red;
	}
</style>

  1. Run the project

  2. Enter something in the email field

  3. Soft refresh with cmd+r

  4. Data is not restored in superforms state <---- problem

  5. Hard refresh (cmd+shift+r)

  6. State is (correctly) reset

  7. un-comment out snapshot

  8. hard refresh

  9. state is not restored <---- major problem

Logs

No response

System Info

System:
    OS: Linux 6.6 Debian GNU/Linux 11 (bullseye) 11 (bullseye)
    CPU: (10) arm64 unknown
    Memory: 2.13 GB / 7.66 GB
    Container: Yes
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 22.12.0 - ~/.local/share/pnpm/node
    npm: 10.9.0 - ~/.local/share/pnpm/npm
    pnpm: 9.15.0 - ~/.local/share/pnpm/pnpm
  npmPackages:
    @sveltejs/kit: ^2.11.1 => 2.11.1 
    formsnap: ^2.0.0 => 2.0.0 
    svelte: ^5.13.0 => 5.13.0 
    sveltekit-superforms: ^2.21.1 => 2.21.1 

npm notice
npm notice New patch version of npm available! 10.9.0 -> 10.9.2
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.9.2
npm notice To update run: npm install -g [email protected]
npm notice

Severity

blocking all usage of Formsnap

@Mardoxx Mardoxx changed the title Breaks superforms restore on soft-reload Breaks superforms restore on soft-reload, and on hard-restore with snapshots enabled Dec 14, 2024
@Mardoxx Mardoxx changed the title Breaks superforms restore on soft-reload, and on hard-restore with snapshots enabled Breaks superforms internal sate restore on soft-reload, and on hard-reload with snapshots enabled Dec 14, 2024
@Mardoxx
Copy link
Author

Mardoxx commented Dec 14, 2024

let formState: ReturnType<typeof capture> | null = null;

function do_capture() {
  formState = capture();
}

function do_restore() {
  if (formState != null) {
    restore(formState);
  }
}
<button onclick={do_capture}>capture</button>
<button onclick={do_restore}>restore</button>

This works, so I guess it is on initial initialisation

@huntabyte
Copy link
Member

Would you mind pushing your code to GitHub and dropping a repo link so I can debug?

@Mardoxx
Copy link
Author

Mardoxx commented Dec 14, 2024

https://github.com/Mardoxx/formsnap-issue/

pnpm install
pnpm dev

https://github.com/Mardoxx/formsnap-issue/blob/main/src/routes/%2Bpage.svelte#L16
coment this line out to validate soft refresh behaviour

@Mardoxx
Copy link
Author

Mardoxx commented Dec 14, 2024

Initial

image

On restore

image

SuperForm internal state seems wrong.


It seems that it is the html input component that is messing things up if I put in

<Field {form} name="email">
	<Control>
		{#snippet children({ props })}
			<Label>Email</Label>
			<input {...props} type="text" bind:value={$formData.email} />
		{/snippet}
	</Control>
	<Description>Use your company email if you have one.</Description>
	<FieldErrors />
</Field>

above the form, it breaks things, if I remove the input, it doesnt't exhibit the bad behaviour

@Mardoxx
Copy link
Author

Mardoxx commented Dec 15, 2024

onMount(() => console.log($formData));

or

<button onclick={() => console.log($formData)}>dump</button>

When SuperDebug reports that the form is in an invalid state, dumping it shows the data to be correct.

This might suggest an issue with SuperDebug component, although I think it is still worth investigating why this behavior has changed. This library is a wrapper around superforms which should cause no side effects on its functionality, this discrepancy is unexpected.

It’s also possible that this issue could lead to bugs in more advanced use cases involving superforms. Investigating it now might help prevent potential problems down the line.

@huntabyte
Copy link
Member

I wonder if it has something to do with this? https://svelte.dev/docs/svelte/bind#input-bind:value

Can you reproduce it without using formsnap at all? If so then this is an issue for sveltekit-superforms rather than formsnap.

@Mardoxx
Copy link
Author

Mardoxx commented Dec 15, 2024 via email

@huntabyte
Copy link
Member

CleanShot.2024-12-15.at.11.44.38.mp4

I apologize, I'm having a difficult time following what is and isn't working as expected. This is the behavior I get when putting the component in runes mode (replace export let data with let { data } = $props()).

Is this not the expected behavior?

@Mardoxx
Copy link
Author

Mardoxx commented Dec 15, 2024

Interesting.. strange, this is after putting it in rune modes

https://www.loom.com/share/d2a924f426a14caca659df3a8e70660c

@Mardoxx
Copy link
Author

Mardoxx commented Dec 15, 2024

Ah.. it's a firefox bug.

Version 133.0.3

@Mardoxx
Copy link
Author

Mardoxx commented Dec 15, 2024

Here it is without formsnap (still in firefox), and it works correctly

https://www.loom.com/share/2e7f6cdf4aae41e6a3600f6b772f3fc8

<script lang="ts">
	import SuperDebug, { superForm } from 'sveltekit-superforms';
	import { valibot } from 'sveltekit-superforms/adapters';
	import { schema } from './schema';

	let { data } = $props();

	const form = superForm(data.form, {
		validators: valibot(schema)
	});

	const { form: formData, message, enhance, capture, restore } = form;

	export const snapshot = { capture, restore };
</script>

{#if $message}<h3>{$message}</h3>{/if}

<form method="POST" use:enhance>
	<input type="text" bind:value={$formData.name} />
	<input type="text" bind:value={$formData.email} />

	<div><button>Submit</button></div>
</form>

<hr />
<p>
	💥 <a target="_blank" href="https://superforms.rocks">Created with Superforms for SvelteKit</a> 💥
</p>
<SuperDebug data={$formData} />

<style>
	.invalid {
		color: red;
	}
</style>

@huntabyte
Copy link
Member

Interesting... I'll take a closer look at this with firefox as soon as I get the chance!

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

No branches or pull requests

2 participants