diff --git a/.changeset/fluffy-lights-know.md b/.changeset/fluffy-lights-know.md new file mode 100644 index 000000000000..00e2e60767bf --- /dev/null +++ b/.changeset/fluffy-lights-know.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: `form.fields.set()` triggers `form.fields.value()` updates diff --git a/packages/kit/src/runtime/client/remote-functions/form.svelte.js b/packages/kit/src/runtime/client/remote-functions/form.svelte.js index 62c97b2f48d2..6d5d7b45fe4a 100644 --- a/packages/kit/src/runtime/client/remote-functions/form.svelte.js +++ b/packages/kit/src/runtime/client/remote-functions/form.svelte.js @@ -540,6 +540,15 @@ export function form(id) { } else { input = deep_set(input, path.map(String), value); } + + const copy = path.slice(); + + do { + const name = build_path_string(copy); + + versions[name] ??= 0; + versions[name] += 1; + } while (copy.pop() !== undefined); }, () => issues ) diff --git a/packages/kit/test/apps/basics/src/routes/remote/form/set/+page.svelte b/packages/kit/test/apps/basics/src/routes/remote/form/set/+page.svelte new file mode 100644 index 000000000000..f32a189d6740 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/remote/form/set/+page.svelte @@ -0,0 +1,19 @@ + + +

Remote Form Set Test

+ +
+ + + +
+ +

Full Form Value

+
{JSON.stringify(values.fields.value(), null, '  ')}
+ + diff --git a/packages/kit/test/apps/basics/src/routes/remote/form/set/value.remote.ts b/packages/kit/test/apps/basics/src/routes/remote/form/set/value.remote.ts new file mode 100644 index 000000000000..f6686abdc12b --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/remote/form/set/value.remote.ts @@ -0,0 +1,11 @@ +import { form } from '$app/server'; +import * as v from 'valibot'; + +export const values = form( + v.object({ + leaf: v.string() + }), + async (data) => { + return { success: true, data }; + } +); diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js index 1e64ded04982..0f44a98a3cc2 100644 --- a/packages/kit/test/apps/basics/test/test.js +++ b/packages/kit/test/apps/basics/test/test.js @@ -1982,6 +1982,26 @@ test.describe('remote functions', () => { expect(JSON.parse(arrayValue)).toEqual([{ leaf: 'array-0-leaf' }, { leaf: 'array-1-leaf' }]); }); + test('form.fields.set() triggers form.fields.value() updates', async ({ + page, + javaScriptEnabled + }) => { + if (!javaScriptEnabled) return; + + await page.goto('/remote/form/set'); + + const before = await page.locator('#full-value').textContent(); + expect(JSON.parse(before)).toEqual({}); + + await page.locator('#update-value').click(); + + const leafValue = await page.locator('input[name="leaf"]').inputValue(); + expect(leafValue).toBe('new value'); + + const after = await page.locator('#full-value').textContent(); + expect(JSON.parse(after)).toEqual({ leaf: 'new value' }); + }); + test('selects are not nuked when unrelated controls change', async ({ page, javaScriptEnabled