Skip to content

Commit

Permalink
[feat] invalidate with predicate (#4636)
Browse files Browse the repository at this point in the history
* [feat] invalidate with predicate

* work around function serialisation problem

* simplify

* update types

Co-authored-by: Rich Harris <hello@rich-harris.dev>
  • Loading branch information
icalvin102 and Rich-Harris committed Apr 18, 2022
1 parent 102c599 commit b4289d5
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/hungry-weeks-exercise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

`invalidate` with `predicate` function
17 changes: 10 additions & 7 deletions packages/kit/src/runtime/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ export function create_client({ target, session, base, trailing_slash }) {
/** @type {Map<string, import('./types').NavigationResult>} */
const cache = new Map();

/** @type {Set<string>} */
const invalidated = new Set();
/** @type {Array<((href: string) => boolean)>} */
const invalidated = [];

const stores = {
url: notifiable_store({}),
Expand Down Expand Up @@ -243,7 +243,7 @@ export function create_client({ target, session, base, trailing_slash }) {
// abort if user navigated during update
if (token !== current_token) return;

invalidated.clear();
invalidated.length = 0;

if (navigation_result.redirect) {
if (redirect_chain.length > 10 || redirect_chain.includes(url.pathname)) {
Expand Down Expand Up @@ -634,7 +634,7 @@ export function create_client({ target, session, base, trailing_slash }) {
(changed.url && previous.uses.url) ||
changed.params.some((param) => previous.uses.params.has(param)) ||
(changed.session && previous.uses.session) ||
Array.from(previous.uses.dependencies).some((dep) => invalidated.has(dep)) ||
Array.from(previous.uses.dependencies).some((dep) => invalidated.some((fn) => fn(dep))) ||
(stuff_changed && previous.uses.stuff);

if (changed_since_last_render) {
Expand Down Expand Up @@ -975,9 +975,12 @@ export function create_client({ target, session, base, trailing_slash }) {
goto: (href, opts = {}) => goto(href, opts, []),

invalidate: (resource) => {
const { href } = new URL(resource, location.href);

invalidated.add(href);
if (typeof resource === 'function') {
invalidated.push(resource);
} else {
const { href } = new URL(resource, location.href);
invalidated.push((dep) => dep === href);
}

if (!invalidating) {
invalidating = Promise.resolve().then(async () => {
Expand Down
1 change: 1 addition & 0 deletions packages/kit/test/apps/basics/src/global.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
declare global {
interface Window {
invalidated: boolean;
oops: string;
pageContext: any;
fulfil_navigation: (value: any) => void;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script context="module">
import { browser } from '$app/env';
import { invalidate } from '$app/navigation';
let count = 0;
Expand Down Expand Up @@ -28,3 +29,10 @@
</script>

<h2>x: {x}: {loads}</h2>

<button
on:click={async () => {
await invalidate((dep) => dep.includes('change-detection/data.json'));
window.invalidated = true;
}}>invalidate change-detection/data.json</button
>
5 changes: 5 additions & 0 deletions packages/kit/test/apps/basics/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,11 @@ test.describe.parallel('Load', () => {
await app.invalidate('custom:change-detection-layout');
expect(await page.textContent('h1')).toBe('layout loads: 4');
expect(await page.textContent('h2')).toBe('x: b: 2');

await page.click('button');
await page.waitForFunction('window.invalidated');
expect(await page.textContent('h1')).toBe('layout loads: 5');
expect(await page.textContent('h2')).toBe('x: b: 2');
}
});

Expand Down
4 changes: 2 additions & 2 deletions packages/kit/types/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ declare module '$app/navigation' {
): Promise<void>;
/**
* Causes any `load` functions belonging to the currently active page to re-run if they `fetch` the resource in question. Returns a `Promise` that resolves when the page is subsequently updated.
* @param href The invalidated resource
* @param dependency The invalidated resource
*/
export function invalidate(href: string): Promise<void>;
export function invalidate(dependency: string | ((href: string) => boolean)): Promise<void>;
/**
* Programmatically prefetches the given page, which means
* 1. ensuring that the code for the page is loaded, and
Expand Down

0 comments on commit b4289d5

Please sign in to comment.