Skip to content

Commit

Permalink
fix: prevent stale values after invalidation (#11870)
Browse files Browse the repository at this point in the history
  • Loading branch information
dummdidumm authored Feb 22, 2024
1 parent 654b73e commit 75e1f5f
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/angry-gorillas-peel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@sveltejs/kit": patch
---

fix: prevent stale values after invalidation
29 changes: 17 additions & 12 deletions packages/kit/src/runtime/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,20 +308,23 @@ async function _invalidate() {

const nav_token = (token = {});
const navigation_result = intent && (await load_route(intent));
if (nav_token !== token) return;
if (!navigation_result || nav_token !== token) return;

if (navigation_result) {
if (navigation_result.type === 'redirect') {
await _goto(new URL(navigation_result.location, current.url).href, {}, 1, nav_token);
} else {
if (navigation_result.props.page !== undefined) {
page = navigation_result.props.page;
}
root.$set(navigation_result.props);
}
if (navigation_result.type === 'redirect') {
return _goto(new URL(navigation_result.location, current.url).href, {}, 1, nav_token);
}

if (navigation_result.props.page) {
page = navigation_result.props.page;
}
current = navigation_result.state;
reset_invalidation();
root.$set(navigation_result.props);
}

function reset_invalidation() {
invalidated.length = 0;
force_invalidation = false;
}

/** @param {number} index */
Expand Down Expand Up @@ -1092,6 +1095,9 @@ async function load_root_error_page({ status, error, url, route }) {
}

/**
* Resolve the full info (which route, params, etc.) for a client-side navigation from the URL,
* taking the reroute hook into account. If this isn't a client-side-navigation (or the URL is undefined),
* returns undefined.
* @param {URL | undefined} url
* @param {boolean} invalidating
*/
Expand Down Expand Up @@ -1281,8 +1287,7 @@ async function navigate({

// reset invalidation only after a finished navigation. If there are redirects or
// additional invalidations, they should get the same invalidation treatment
invalidated.length = 0;
force_invalidation = false;
reset_invalidation();

updating = true;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import('./$types').LayoutServerLoad} */
export function load({ depends }) {
depends('invalidate-depends:goto');
return {
layoutDate: new Date().getTime()
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import('./$types').PageServerLoad} */
export function load({ url }) {
url.searchParams.get('x');
return {
pageDate: new Date().getTime()
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script>
import { invalidate, goto } from '$app/navigation';
/** @type {import('./$types').PageData} */
export let data;
</script>

<p class="layout">{data.layoutDate}</p>
<p class="page">{data.pageDate}</p>
<button
type="button"
class="invalidate"
on:click={() => (window.promise = invalidate('invalidate-depends:goto'))}
>
invalidate
</button>
<button
type="button"
class="goto"
on:click={() => (window.promise = goto('/load/invalidation/invalidate-then-goto?x'))}
>
goto
</button>
22 changes: 22 additions & 0 deletions packages/kit/test/apps/basics/test/client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,28 @@ test.describe('Invalidation', () => {
await page.locator('button').click();
await expect(page.getByText('updated')).toBeVisible();
});

test('goto after invalidation does not reset state', async ({ page }) => {
await page.goto('/load/invalidation/invalidate-then-goto');
const layout = await page.textContent('p.layout');
const _page = await page.textContent('p.page');
expect(layout).toBeDefined();
expect(_page).toBeDefined();

await page.click('button.invalidate');
await page.evaluate(() => window.promise);
const next_layout_1 = await page.textContent('p.layout');
const next_page_1 = await page.textContent('p.page');
expect(next_layout_1).not.toBe(layout);
expect(next_page_1).toBe(_page);

await page.click('button.goto');
await page.evaluate(() => window.promise);
const next_layout_2 = await page.textContent('p.layout');
const next_page_2 = await page.textContent('p.page');
expect(next_layout_2).toBe(next_layout_1);
expect(next_page_2).not.toBe(next_page_1);
});
});

test.describe('data-sveltekit attributes', () => {
Expand Down

0 comments on commit 75e1f5f

Please sign in to comment.