fix: make query.refresh lazy, inline results during render - #16461
fix: make query.refresh lazy, inline results during render#16461elliott-with-the-longest-name-on-github merged 10 commits into
query.refresh lazy, inline results during render#16461Conversation
|
Install the latest version of pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/be95209dfe5c3ca197536140637ef645b2264646Open in |
🦋 Changeset detectedLatest commit: be95209 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Nic-Polumeyv
left a comment
There was a problem hiding this comment.
One execution-order regression inline.
| // `fn` is invoked here, at the end of the request. If the query was | ||
| // already read earlier (repopulating the cache) `fn` reuses that cached | ||
| // promise and does no additional work; otherwise it runs the query now. | ||
| await fn().then( |
There was a problem hiding this comment.
Each fn() now starts only after the previous one settled, the eager version had them all in flight before the loop. Starting them together needs handlers attached at start (the old no-op catch) and must keep picking up entries a lazily-run query adds by refreshing another:
if (state.remote.explicit) {
/** @type {Set<string>} */
const processed = new Set();
// `state.remote.explicit` can grow while we collect (a lazily-run query can
// refresh another), so sweep until it stops growing
while (processed.size < state.remote.explicit.size) {
/** @type {Promise<void>[]} */
const batch = [];
for (const [remote_key, { internals, fn }] of state.remote.explicit) {
if (processed.has(remote_key)) continue;
processed.add(remote_key);
// there were explicit refreshes/reconnects (via `refresh()`/`set()`/`reconnect()`),
// so the client should apply these single-flight updates instead of calling `invalidateAll()`
data.r = true;
const type = /** @type {'p' | 'q' | 'l'} */ (
internals.type === 'query_live' ? 'l' : internals.type[0]
);
batch.push(
fn().then(
(v) => {
((data[type] ??= {})[remote_key] ??= {}).v = v;
},
async (e) => {
if (e instanceof Redirect) {
// already handled elsewhere
return;
}
((data[type] ??= {})[remote_key] ??= {}).e = await convert_error(e);
}
)
);
}
await Promise.all(batch);
}
}…t-inlining # Conflicts: # packages/kit/src/runtime/app/server/remote/query.js # packages/kit/src/runtime/server/remote-functions.js
|
Still not quite happy with this... going to investigate a drain loop so that queries that call |
Rich-Harris
left a comment
There was a problem hiding this comment.
small inline suggestion, and there's a lint failure, but otherwise LGTM
4b4cc60
into
version-3
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to version-3, this PR will be updated.⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ `version-3` is currently in **pre mode** so this branch has prereleases rather than normal releases. If you want to exit prereleases, run `changeset pre exit` on `version-3`.⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ # Releases ## @sveltejs/kit@3.0.0-next.12 ### Major Changes - breaking: rename `Pathname` type to `Path` and `Asset` to `AssetPath` ([#16430](#16430)) breaking: remove leading `/` from `Path` and `AssetPath` - breaking: write tsconfig to `node_modules/$app/tsconfig` ([#16458](#16458)) - breaking: error on `event.url`, `event.params` and `event.route` access inside queries ([#16452](#16452)) - breaking: delete `$service-worker` module ([#16450](#16450)) - breaking: detect new deployments on data, remote, and form action responses, tab focus, and visibility change, and default `version.pollInterval` to 1 hour ([#16496](#16496)) ### Minor Changes - feat: add `$app/manifest` module with `immutable`, `assets`, `prerendered`, and `routes` exports ([#16372](#16372)) - feat: validate that all remote form fields were created with form.fields.foo.as(...) ([#16331](#16331)) - feat: make `$app/paths` importable in service workers ([#16441](#16441)) - feat: `$app/service-worker` module ([#16458](#16458)) - feat: better tsconfig validation ([#16458](#16458)) - fix: default cookies to `secure` to `false` during development ([#16462](#16462)) ### Patch Changes - fix: allow `undefined` values to be passed to form field `.as(...)` where applicable ([#15681](#15681)) - fix: include queries refreshed from within another query in the serialized response ([#16461](#16461)) - fix: generate sourcemaps for remote modules ([#16440](#16440)) - fix: avoid empty getElementById() call on hash routing navigation ([#16448](#16448)) - fix: warn if hook files are spelled as "hook" instead of "hooks" ([#16483](#16483)) - chore: deprecate the `alias` option ([#16470](#16470)) - fix: prevent infinite loops when server-side queries refresh each other in a cycle during the single-flight drain ([#16461](#16461)) - fix: populate `version` in service workers ([#16434](#16434)) - fix: resolve remote modules as external during dev prebundling so packages can re-export remote functions ([#16426](#16426)) - fix: refetch route-tracking server data when navigating away from an error page ([#16381](#16381)) - fix: serialize `query(...).set(...)`/`query(...).refresh()` values into the rendered HTML when called from within a query during SSR ([#16461](#16461)) - fix: fall back to the page's form actions when a sibling endpoint has no POST handler ([#16349](#16349)) - fix: return a lightweight 404 instead of rendering the error page for subresource requests ([#16463](#16463)) - fix: preserve stripped path prefixes by making trailing-slash redirects relative ([#16431](#16431)) - chore: deduplicate type-stripping logic in `tweak_types` ([#16454](#16454)) - fix: more informative error message when running a command inside a query or prerender function ([`eb5c973`](eb5c973)) ## @sveltejs/adapter-cloudflare@8.0.0-next.3 ### Patch Changes - chore: bump `@cloudflare/workers-types` to `4.20260621.1` ([#16455](#16455)) - Updated dependencies [[`adc4c5b`](adc4c5b), [`ecb0701`](ecb0701), [`4b4cc60`](4b4cc60), [`7390dbe`](7390dbe), [`2e71340`](2e71340), [`c87bc3a`](c87bc3a), [`af15c6c`](af15c6c), [`c6fa431`](c6fa431), [`bfe4dea`](bfe4dea), [`df7dc72`](df7dc72), [`5ae11a1`](5ae11a1), [`781205c`](781205c), [`c87bc3a`](c87bc3a), [`a1bfeb9`](a1bfeb9), [`c87bc3a`](c87bc3a), [`9f0127d`](9f0127d), [`4b4cc60`](4b4cc60), [`8f5b9c7`](8f5b9c7), [`c9b5544`](c9b5544), [`fe1d4a4`](fe1d4a4), [`4b4cc60`](4b4cc60), [`5f78e95`](5f78e95), [`25510fc`](25510fc), [`c99a6cf`](c99a6cf), [`17a45ca`](17a45ca), [`2ca20c3`](2ca20c3), [`eb5c973`](eb5c973)]: - @sveltejs/kit@3.0.0-next.12 ## @sveltejs/adapter-netlify@7.0.0-next.4 ### Patch Changes - fix: await `init` on every request to prevent race condition ([#16467](#16467)) - chore: bump Rolldown to `1.2.0` ([#16455](#16455)) - Updated dependencies [[`adc4c5b`](adc4c5b), [`ecb0701`](ecb0701), [`4b4cc60`](4b4cc60), [`7390dbe`](7390dbe), [`2e71340`](2e71340), [`c87bc3a`](c87bc3a), [`af15c6c`](af15c6c), [`c6fa431`](c6fa431), [`bfe4dea`](bfe4dea), [`df7dc72`](df7dc72), [`5ae11a1`](5ae11a1), [`781205c`](781205c), [`c87bc3a`](c87bc3a), [`a1bfeb9`](a1bfeb9), [`c87bc3a`](c87bc3a), [`9f0127d`](9f0127d), [`4b4cc60`](4b4cc60), [`8f5b9c7`](8f5b9c7), [`c9b5544`](c9b5544), [`fe1d4a4`](fe1d4a4), [`4b4cc60`](4b4cc60), [`5f78e95`](5f78e95), [`25510fc`](25510fc), [`c99a6cf`](c99a6cf), [`17a45ca`](17a45ca), [`2ca20c3`](2ca20c3), [`eb5c973`](eb5c973)]: - @sveltejs/kit@3.0.0-next.12 ## @sveltejs/adapter-node@6.0.0-next.6 ### Patch Changes - fix: preserve stripped path prefixes by making trailing-slash redirects relative ([#16431](#16431)) - chore: bump Rolldown to `1.2.0` ([#16455](#16455)) - Updated dependencies [[`adc4c5b`](adc4c5b), [`ecb0701`](ecb0701), [`4b4cc60`](4b4cc60), [`7390dbe`](7390dbe), [`2e71340`](2e71340), [`c87bc3a`](c87bc3a), [`af15c6c`](af15c6c), [`c6fa431`](c6fa431), [`bfe4dea`](bfe4dea), [`df7dc72`](df7dc72), [`5ae11a1`](5ae11a1), [`781205c`](781205c), [`c87bc3a`](c87bc3a), [`a1bfeb9`](a1bfeb9), [`c87bc3a`](c87bc3a), [`9f0127d`](9f0127d), [`4b4cc60`](4b4cc60), [`8f5b9c7`](8f5b9c7), [`c9b5544`](c9b5544), [`fe1d4a4`](fe1d4a4), [`4b4cc60`](4b4cc60), [`5f78e95`](5f78e95), [`25510fc`](25510fc), [`c99a6cf`](c99a6cf), [`17a45ca`](17a45ca), [`2ca20c3`](2ca20c3), [`eb5c973`](eb5c973)]: - @sveltejs/kit@3.0.0-next.12 ## @sveltejs/adapter-vercel@7.0.0-next.3 ### Patch Changes - fix: await `init` on every request to prevent race condition ([#16467](#16467)) - chore: bump Rolldown to `1.2.0` ([#16455](#16455)) - Updated dependencies [[`adc4c5b`](adc4c5b), [`ecb0701`](ecb0701), [`4b4cc60`](4b4cc60), [`7390dbe`](7390dbe), [`2e71340`](2e71340), [`c87bc3a`](c87bc3a), [`af15c6c`](af15c6c), [`c6fa431`](c6fa431), [`bfe4dea`](bfe4dea), [`df7dc72`](df7dc72), [`5ae11a1`](5ae11a1), [`781205c`](781205c), [`c87bc3a`](c87bc3a), [`a1bfeb9`](a1bfeb9), [`c87bc3a`](c87bc3a), [`9f0127d`](9f0127d), [`4b4cc60`](4b4cc60), [`8f5b9c7`](8f5b9c7), [`c9b5544`](c9b5544), [`fe1d4a4`](fe1d4a4), [`4b4cc60`](4b4cc60), [`5f78e95`](5f78e95), [`25510fc`](25510fc), [`c99a6cf`](c99a6cf), [`17a45ca`](17a45ca), [`2ca20c3`](2ca20c3), [`eb5c973`](eb5c973)]: - @sveltejs/kit@3.0.0-next.12 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Supersedes #16428. It had the right approach, but we were actually handling
refreshwrong in the first place. I thought we'd implemented this behavior but somehow we haven't.Anyway, this kills two birds with one stone:
.refresh(and.set) to run during render.refreshlazy: Calling.refreshbusts the cache and guarantees that the cache will be populated by the end of the request. If youawaitthe query or access its data, it will immediately run and populate the cache; otherwise SvelteKit will do it at the end of the request, in parallel with any other refreshing queries