From 2ad4826a83a9902d67065ac97a92981f8d2dc12e Mon Sep 17 00:00:00 2001 From: icalvin102 Date: Wed, 6 Apr 2022 01:00:40 +0200 Subject: [PATCH 1/6] [feat] custom load dependencies --- packages/kit/src/runtime/client/client.js | 12 ++++++++++-- packages/kit/src/runtime/load.js | 17 +++++++++++++---- packages/kit/types/internal.d.ts | 1 + packages/kit/types/private.d.ts | 1 + 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js index 37e566aa551c..86765fa9e595 100644 --- a/packages/kit/src/runtime/client/client.js +++ b/packages/kit/src/runtime/client/client.js @@ -477,6 +477,12 @@ export function create_client({ target, session, base, trailing_slash }) { stuff }; + /** @param dep {string} */ + function addDependency(dep) { + const { href } = new URL(dep, url); + node.uses.dependencies.add(href); + } + if (props) { // shadow endpoint props means we need to mark this URL as a dependency of itself node.uses.dependencies.add(url.href); @@ -516,8 +522,7 @@ export function create_client({ target, session, base, trailing_slash }) { }, fetch(resource, info) { const requested = typeof resource === 'string' ? resource : resource.url; - const { href } = new URL(requested, url); - node.uses.dependencies.add(href); + addDependency(requested); return started ? fetch(resource, info) : initial_fetch(resource, info); } @@ -545,6 +550,9 @@ export function create_client({ target, session, base, trailing_slash }) { node.loaded = normalize(loaded); if (node.loaded.stuff) node.stuff = node.loaded.stuff; + if (node.loaded.dependencies) { + node.loaded.dependencies.forEach(addDependency); + } } else if (props) { node.loaded = normalize({ props }); } diff --git a/packages/kit/src/runtime/load.js b/packages/kit/src/runtime/load.js index b16097b5763c..c50da95226c2 100644 --- a/packages/kit/src/runtime/load.js +++ b/packages/kit/src/runtime/load.js @@ -9,10 +9,7 @@ export function normalize(loaded) { const status = loaded.status; if (!loaded.error && has_error_status) { - return { - status: status || 500, - error: new Error() - }; + return { status: status || 500, error: new Error() }; } const error = typeof loaded.error === 'string' ? new Error(loaded.error) : loaded.error; @@ -52,6 +49,18 @@ export function normalize(loaded) { } } + if (loaded.dependencies) { + if ( + !Array.isArray(loaded.dependencies) || + loaded.dependencies.some((dep) => typeof dep !== 'string') + ) { + return { + status: 500, + error: new Error('"dependencies" property returned from load() must be of type string[]') + }; + } + } + // TODO remove before 1.0 if (/** @type {any} */ (loaded).context) { throw new Error( diff --git a/packages/kit/types/internal.d.ts b/packages/kit/types/internal.d.ts index 37c0a7fb6d1f..a6496bbef193 100644 --- a/packages/kit/types/internal.d.ts +++ b/packages/kit/types/internal.d.ts @@ -118,6 +118,7 @@ export type NormalizedLoadOutput = { props?: Record | Promise>; stuff?: Record; maxage?: number; + dependencies?: string[]; }; export interface PageData { diff --git a/packages/kit/types/private.d.ts b/packages/kit/types/private.d.ts index f2a74d7b118a..1222f5d5f5c3 100644 --- a/packages/kit/types/private.d.ts +++ b/packages/kit/types/private.d.ts @@ -176,6 +176,7 @@ export interface LoadOutput = Record; maxage?: number; + dependencies?: string[]; } export interface Logger { From 753c8becfd0207761f82dd062ee0a93323a35173 Mon Sep 17 00:00:00 2001 From: icalvin102 Date: Wed, 6 Apr 2022 02:05:53 +0200 Subject: [PATCH 2/6] [test] custom load dependencies --- .../basics/src/routes/load/change-detection/__layout.svelte | 3 ++- packages/kit/test/apps/basics/test/test.js | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/kit/test/apps/basics/src/routes/load/change-detection/__layout.svelte b/packages/kit/test/apps/basics/src/routes/load/change-detection/__layout.svelte index 15fd75f299f7..aca5f5bed680 100644 --- a/packages/kit/test/apps/basics/src/routes/load/change-detection/__layout.svelte +++ b/packages/kit/test/apps/basics/src/routes/load/change-detection/__layout.svelte @@ -13,7 +13,8 @@ props: { type, loads: count - } + }, + dependencies: ['custom:change-detection-layout'] }; } diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js index a3836af3f016..990cbf47af9c 100644 --- a/packages/kit/test/apps/basics/test/test.js +++ b/packages/kit/test/apps/basics/test/test.js @@ -1192,6 +1192,10 @@ test.describe.parallel('Load', () => { await app.invalidate('/load/change-detection/data.json'); expect(await page.textContent('h1')).toBe('layout loads: 3'); expect(await page.textContent('h2')).toBe('x: b: 2'); + + 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'); } }); From c85ee06cabfa371fa06020d8eaf3457172b15151 Mon Sep 17 00:00:00 2001 From: icalvin102 Date: Wed, 6 Apr 2022 02:52:08 +0200 Subject: [PATCH 3/6] [docs] custom load dependencies --- documentation/docs/03-loading.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/documentation/docs/03-loading.md b/documentation/docs/03-loading.md index 57e2a75a8052..42938b16e776 100644 --- a/documentation/docs/03-loading.md +++ b/documentation/docs/03-loading.md @@ -126,3 +126,11 @@ If the `load` function returns a `props` object, the props will be passed to the This will be merged with any existing `stuff` and passed to the `load` functions of subsequent layout and page components. The combined `stuff` is available to components using the [page store](/docs/modules#$app-stores) as `$page.stuff`, providing a mechanism for pages to pass data 'upward' to layouts. + +#### dependencies + +If the `load` function depends on custom resources a `dependencies` array can returned. A registered dependency can later be used as argument of `invalidate` to rerun the `load` function. + +> Note that the `fetch` function alreay registers the requested resources as dependencies. Manual registration is only necessary if it's not possible to use SvelteKits `fetch` function. + +The items should be [properly encoded](https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding) URIs. Both absolute and relative URIs are acceptable. From b4b896666ae3b55286ababceaf97d9545da4ea44 Mon Sep 17 00:00:00 2001 From: icalvin102 Date: Wed, 6 Apr 2022 03:07:06 +0200 Subject: [PATCH 4/6] [changeset] custom load dependencies --- .changeset/breezy-mayflies-yawn.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/breezy-mayflies-yawn.md diff --git a/.changeset/breezy-mayflies-yawn.md b/.changeset/breezy-mayflies-yawn.md new file mode 100644 index 000000000000..dc50ecd65e51 --- /dev/null +++ b/.changeset/breezy-mayflies-yawn.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +Custom `load` `dependencies` in `LoadOutput` From 41b9624dbc5137071750ba4c2e7aeffe53d1a3c0 Mon Sep 17 00:00:00 2001 From: icalvin102 Date: Wed, 6 Apr 2022 03:46:48 +0200 Subject: [PATCH 5/6] [fix] wrong case --- packages/kit/src/runtime/client/client.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js index 86765fa9e595..d85a053a9134 100644 --- a/packages/kit/src/runtime/client/client.js +++ b/packages/kit/src/runtime/client/client.js @@ -478,7 +478,7 @@ export function create_client({ target, session, base, trailing_slash }) { }; /** @param dep {string} */ - function addDependency(dep) { + function add_dependency(dep) { const { href } = new URL(dep, url); node.uses.dependencies.add(href); } @@ -522,7 +522,7 @@ export function create_client({ target, session, base, trailing_slash }) { }, fetch(resource, info) { const requested = typeof resource === 'string' ? resource : resource.url; - addDependency(requested); + add_dependency(requested); return started ? fetch(resource, info) : initial_fetch(resource, info); } @@ -551,7 +551,7 @@ export function create_client({ target, session, base, trailing_slash }) { node.loaded = normalize(loaded); if (node.loaded.stuff) node.stuff = node.loaded.stuff; if (node.loaded.dependencies) { - node.loaded.dependencies.forEach(addDependency); + node.loaded.dependencies.forEach(add_dependency); } } else if (props) { node.loaded = normalize({ props }); From 652f4321dfa38360f500fada2f87971d40ccbc78 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 14 Apr 2022 18:41:41 -0400 Subject: [PATCH 6/6] Update documentation/docs/04-loading.md --- documentation/docs/04-loading.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/documentation/docs/04-loading.md b/documentation/docs/04-loading.md index 2cac58e051a0..4477bcddb6e1 100644 --- a/documentation/docs/04-loading.md +++ b/documentation/docs/04-loading.md @@ -137,8 +137,6 @@ The combined `stuff` is available to components using the [page store](/docs/mod #### dependencies -If the `load` function depends on custom resources a `dependencies` array can returned. A registered dependency can later be used as argument of `invalidate` to rerun the `load` function. +An array of strings representing URLs the page depends on, which can subsequently be used with [`invalidate`](/docs/modules#$app-navigation-invalidate) to cause `load` to rerun. You only need to add them to `dependencies` if you're using a custom API client; URLs loaded with the provided `fetch` function are added automatically. -> Note that the `fetch` function alreay registers the requested resources as dependencies. Manual registration is only necessary if it's not possible to use SvelteKits `fetch` function. - -The items should be [properly encoded](https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding) URIs. Both absolute and relative URIs are acceptable. +URLs can be absolute or relative to the page being loaded, and must be [encoded](https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding).