Skip to content

Commit

Permalink
feat: Allow bypassing invalidateAll in enhance (#9889)
Browse files Browse the repository at this point in the history
* feat: Allow bypassing `invalidateAll` in `enhance`

* changeset

* typedoc

* oops

* cleanup

* Update .changeset/shaggy-trainers-drum.md

* technically fixed, though types will have to catch up

* Revert "technically fixed, though types will have to catch up"

oops, wrong branch

This reverts commit a9ae11b.

* Update .changeset/shaggy-trainers-drum.md

Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>

* Update packages/kit/test/apps/dev-only/package.json

Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>

* fix: Types

---------

Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Rich Harris <richard.a.harris@gmail.com>
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
  • Loading branch information
4 people authored Oct 23, 2023
1 parent 96993cf commit 050447a
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/shaggy-trainers-drum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': minor
---

feat: add `invalidateAll` boolean option to `enhance` callback
3 changes: 2 additions & 1 deletion packages/kit/src/exports/public.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1282,8 +1282,9 @@ export type SubmitFunction<
/**
* Call this to get the default behavior of a form submission response.
* @param options Set `reset: false` if you don't want the `<form>` values to be reset after a successful submission.
* @param invalidateAll Set `invalidateAll: false` if you don't want the action to call `invalidateAll` after submission.
*/
update(options?: { reset: boolean }): Promise<void>;
update(options?: { reset?: boolean; invalidateAll?: boolean }): Promise<void>;
}) => void)
>;

Expand Down
22 changes: 18 additions & 4 deletions packages/kit/src/runtime/app/forms.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,25 @@ export function enhance(form_element, submit = () => {}) {
/**
* @param {{
* action: URL;
* invalidateAll?: boolean;
* result: import('@sveltejs/kit').ActionResult;
* reset?: boolean
* }} opts
*/
const fallback_callback = async ({ action, result, reset }) => {
const fallback_callback = async ({
action,
result,
reset = true,
invalidateAll: shouldInvalidateAll = true
}) => {
if (result.type === 'success') {
if (reset !== false) {
if (reset) {
// We call reset from the prototype to avoid DOM clobbering
HTMLFormElement.prototype.reset.call(form_element);
}
await invalidateAll();
if (shouldInvalidateAll) {
await invalidateAll();
}
}

// For success/failure results, only apply action if it belongs to the
Expand Down Expand Up @@ -222,7 +230,13 @@ export function enhance(form_element, submit = () => {}) {
return form_element;
},
formElement: form_element,
update: (opts) => fallback_callback({ action, result, reset: opts?.reset }),
update: (opts) =>
fallback_callback({
action,
result,
reset: opts?.reset,
invalidateAll: opts?.invalidateAll
}),
// @ts-expect-error generic constraints stuff we don't care about
result
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export function load() {
return {
changes_every_load: new Date()
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export function load({ url }) {
const invalidate_all = url.searchParams.get('invalidate_all') === 'true';
return {
invalidate_all
};
}

export const actions = {
default: () => {}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script>
import { enhance } from '$app/forms';
export let data;
/**
* @param {HTMLFormElement} node
*/
function enhanceWrapper(node) {
return enhance(
node,
() =>
({ update }) =>
update({ invalidateAll: data.invalidate_all })
);
}
</script>

<form method="POST" use:enhanceWrapper>
<pre>{data.changes_every_load.toISOString()}</pre>
<button type="submit">invalidate</button>
</form>
26 changes: 26 additions & 0 deletions packages/kit/test/apps/basics/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,32 @@ test.describe('Matchers', () => {
});

test.describe('Actions', () => {
test("invalidateAll = false doesn't invalidate all", async ({ page, javaScriptEnabled }) => {
await page.goto('/actions/invalidate-all?invalidate_all=false');
const preSubmitContent = await page.locator('pre').textContent();
await page.click('button');
// The value that should not change is time-based and might not have the granularity to change
// if we don't give it time to
await page.waitForTimeout(1000);
const postSubmitContent = await page.locator('pre').textContent();
if (!javaScriptEnabled) {
expect(preSubmitContent).not.toBe(postSubmitContent);
} else {
expect(preSubmitContent).toBe(postSubmitContent);
}
});

test('invalidateAll = true does invalidate all', async ({ page }) => {
await page.goto('/actions/invalidate-all?invalidate_all=true');
const preSubmitContent = await page.locator('pre').textContent();
await page.click('button');
// The value that should not change is time-based and might not have the granularity to change
// if we don't give it time to
await page.waitForTimeout(1000);
const postSubmitContent = await page.locator('pre').textContent();
expect(preSubmitContent).not.toBe(postSubmitContent);
});

test('Submitting a form with a file input but no enctype="multipart/form-data" logs a warning', async ({
page,
javaScriptEnabled
Expand Down

0 comments on commit 050447a

Please sign in to comment.