Fixes#16850, fixes#16775, fixes#16795, fixes#16982#16631 introduced a bug that results in the effects within guards being evaluated before the guards themselves. This fix makes sure to iterate the block effects in the correct order (top down)
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
* WIP implement `$effect.pending(...)`
* feat: `$state.eager(value)` (#16926)
* runtime-first approach
* revert these
* type safety, lint
* fix: better input cursor restoration for `bind:value` (#16925)
If cursor was at end and new input is longer, move cursor to new end
No test because not possible to reproduce using our test setup.
Follow-up to #14649, helps with #16577
* Version Packages (#16920)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* docs: await no longer need pending (#16900)
* docs: link to custom renderer issue in Svelte Native discussion (#16896)
* fix code block (#16937)
Updated code block syntax from Svelte to JavaScript for clarity.
* fix: unset context on stale promises (#16935)
* fix: unset context on stale promises
When a stale promise is rejected in `async_derived`, and the promise eventually resolves, `d.resolve` will be noop and `d.promise.then(handler, ...)` will never run. That in turns means any restored context (via `(await save(..))()`) will never be unset. We have to handle this case and unset the context to prevent errors such as false-positive state mutation errors
* fix: unset context on stale promises (slightly different approach) (#16936)
* slightly different approach to #16935
* move unset_context call
* get rid of logs
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: svg `radialGradient` `fr` attribute missing in types (#16943)
* fix(svg radialGradient): fr attribute missing in types
* chore: add changeset
* Version Packages (#16940)
* Version Packages
* Update packages/svelte/CHANGELOG.md
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* chore: simplify `batch.apply()` (#16945)
* chore: simplify `batch.apply()`
* belt and braces
* note to self
* unused
* fix: don't rerun async effects unnecessarily (#16944)
Since #16866, when an async effect runs multiple times, we rebase older batches and rerun those effects. This can have unintended consequences: In a case where an async effect only depends on a single source, and that single source was updated in a later batch, we know that we don't need to / should not rerun the older batch.
This PR makes it so: We collect all the sources of older batches that are not part of the current batch that just committed, and then only mark those async effects as dirty which depend on one of those other sources. Fixes the bug I noticed while working on #16935
* fix: ensure map iteration order is correct (#16947)
quick follow-up to #16944
Resetting a map entry does not change its position in the map when iterating. We need to make sure that reset makes that batch jump "to the front" for the "reject all stale batches" logic below. Edge case for which I can't come up with a test case but it _is_ a possibility.
* feat: add `createContext` utility for type-safe context (#16948)
* feat: add `createContext` utility for type-safe context
* regenerate
* Version Packages (#16946)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* chore: Remove annoying sync-async warning (#16949)
* fix
* use `$state.eager(value)` instead of `$effect.pending(value)`
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hyunbin Seo <47051820+hyunbinseo@users.noreply.github.com>
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Hannes Rüger <hannes@hannesrueger.de>
Co-authored-by: Elliott Johnson <sejohnson@torchcloudconsulting.com>
* decouple from boundaries
* use queue_micro_task
* add test
* fix
* changeset
* revert
* tidy up
* update docs
* Update packages/svelte/src/internal/client/reactivity/batch.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* minor tweak
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hyunbin Seo <47051820+hyunbinseo@users.noreply.github.com>
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
Co-authored-by: Hannes Rüger <hannes@hannesrueger.de>
Co-authored-by: Elliott Johnson <sejohnson@torchcloudconsulting.com>
quick follow-up to #16944
Resetting a map entry does not change its position in the map when iterating. We need to make sure that reset makes that batch jump "to the front" for the "reject all stale batches" logic below. Edge case for which I can't come up with a test case but it _is_ a possibility.
Since #16866, when an async effect runs multiple times, we rebase older batches and rerun those effects. This can have unintended consequences: In a case where an async effect only depends on a single source, and that single source was updated in a later batch, we know that we don't need to / should not rerun the older batch.
This PR makes it so: We collect all the sources of older batches that are not part of the current batch that just committed, and then only mark those async effects as dirty which depend on one of those other sources. Fixes the bug I noticed while working on #16935
* fix: unset context on stale promises
When a stale promise is rejected in `async_derived`, and the promise eventually resolves, `d.resolve` will be noop and `d.promise.then(handler, ...)` will never run. That in turns means any restored context (via `(await save(..))()`) will never be unset. We have to handle this case and unset the context to prevent errors such as false-positive state mutation errors
* fix: unset context on stale promises (slightly different approach) (#16936)
* slightly different approach to #16935
* move unset_context call
* get rid of logs
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
If cursor was at end and new input is longer, move cursor to new end
No test because not possible to reproduce using our test setup.
Follow-up to #14649, helps with #16577
Test for #16912
Also some explanation what the bug was:
1. async batch kicks off
2. outer async work succeeds, still something pending, so doesn't do anything for now
3. something unrelated writes to a signal (in the remote functions case it's the query writing to loading, raw etc), which creates a new batch
4. new batch executes. since there are multiple batches it takes the previous value which means if block is still alive. commits that, since no async work from the perspective of this branch
5. inner async work succeeds. now the batch has zero pending async work so it can flush. But the if block is no longer dirty since it was done by the other batch already -> never undos the other work
#16912 fixes it by still traversing the tree which means the if block deletion is scheduled to commit later, which it then does
We have an each block optimization that omits the comment when the each block is the sole child of an element. This optimization clashes with async which wants to skip ahead to the sibling closing comment.
For now we therefore remove that optimization when the each block is async. In the long run we should instead optimize _all_ cases where _any_ block is the sole child of an element, in both async and sync mode, consistently.
fixes#16905fixes#16907
* fix: update error message to clarify usage with radio inputs
* show an extra bind checked error when a radio type
* typo
* replace 'group' binding with , drive-by fix some other messages
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Race them against each other - in almost all cases requestAnimationFrame will fire first, but e.g. in case the window is not focused or a view transition happens, requestAnimationFrame will be delayed and setTimeout helps us resolve fast enough in that case
Fixes#16429
Fixes https://github.com/sveltejs/kit/issues/14220
* fix: depend on reads of deriveds created within reaction (async mode)
As part of https://github.com/sveltejs/kit/pull/14481 we discovered that deriveds created within reactions and reading from them in that same reaction is actually useful in some cases, as such a use case we couldn't imagine yet in #15564 has appeared.
We think it's ultimately better to rerun on those cases, so we're going to make this change in async mode (that way the behavior doesn't change unless you have enabled the experimental flag)
* fix tests
Fixes#16816Fixes#16811
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* feat: First pass at payload
* first crack
* snapshots
* checkpoint
* fix: cloning
* add test option
* big dumb
* today's hard work; few tests left to fix
* improve
* tests passing no wayyyyy yo
* lots of progress, couple of failing tests around selects
* meh
* solve async tree stuff
* fix select/option stuff
* whoop, tests
* simplify
* feat: hoisting
* fix: `$effect.pending` sends updates to incorrect boundary
* changeset
* stuff from upstream
* feat: first hydrationgaa
* remove docs
* snapshots
* silly fix
* checkpoint
* meh
* ALKASJDFALSKDFJ the test passes
* chore: Update a bunch of tests for hydration markers
* chore: remove snippet and is_async
* naming
* better errors for sync-in-async
* test improvements
* idk man
* merge local branches (#16757)
* use fragment as async hoist boundary
* remove async_hoist_boundary
* only dewaterfall when necessary
* unused
* simplify/fix
* de-waterfall awaits in separate elements
* update snapshots
* remove unnecessary wrapper
* fix
* fix
* remove suspends_without_fallback
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* Update payload.js
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* checkpoint
* got the extra children to go away
* just gonna go ahead and merge this as the review comments take up too much space
* chore: remove hoisted_promises (#16766)
* chore: remove hoisted_promises
* WIP optimise promises
* WIP
* fix <slot> with await in prop
* tweak
* fix type error
* Update packages/svelte/src/compiler/phases/3-transform/server/visitors/SvelteHead.js
* chore: fix hydration treeshaking (#16767)
* chore: fix hydration treeshaking
* fix
* remove await_outside_boundary error (#16762)
* chore: remove unused analysis.boundary (#16763)
* chore: simplify slots (#16765)
* chore: simplify slots
* unused
* Apply suggestions from code review
* chore: remove metadata.pending (#16764)
* Update packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js
* put this back where it was, keep the diff small
* Update packages/svelte/src/compiler/phases/types.d.ts
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* chore: remove analysis.state.title (#16771)
* chore: remove analysis.state.title
* unused
* chore: remove is_async (#16769)
* chore: remove is_async
* unused
* Apply suggestions from code review
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* cleanup
* lint
* clean up payload a bit
* compiler work
* run ssr on sync and async
* prettier
* inline capture
* Update packages/svelte/src/compiler/phases/3-transform/server/visitors/EachBlock.js
* chore: simplify build_template (#16780)
* small tweak to aid greppability
* chore: fix SSR context (#16781)
* at least passing
* cleanup
* fix
* remove push/pop from exports, not needed with payload
* I think this is better but tbh not sure
* async SSR
* qualification
* errors:
* I have lost the plot
* finally
* ugh
* tweak error codes to better align with existing conventions, such as they are
* tweak messages
* remove unused args
* DRY out a bit
* unused
* unused
* unused
* simplify - we can enforce readonly at a type level
* unused
* simplify
* avoid magical accessors
* simplify algorithm
* unused
* unused
* reduce indirection
* TreeState -> SSRState
* mark deprecated methods
* grab this.local from parent directly
* rename render -> fn per conventions (fn indicates 'arbitrary code')
* reduce indirection
* Revert "reduce indirection"
This reverts commit 3ec461baad.
* tweak
* okay works this time
* no way chat, it works
* fix context stuff
* tweak
* make it chainable
* lint
* clean up
* lint
* Update packages/svelte/src/internal/server/types.d.ts
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* sunset html for async
* types
* we use 'deprecated' in other messages
* oops
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
#16773 added a test with _expected.html to a wrong suit, so it was ignored, and this allowed to slip in a new bug of printing the falsy hidden attribute as hidden (shortened enabled form).
That fix wasn't released yet, so no changeset.
* chore: generate CSS hash using the filename
* fix all tests but one
* slightly kludgy fix
* try this
* fix
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Consolidates our scheduling system that had diverged into two - queue_micro_task and Batch.ensure-queues and resolves some edge case race conditions related to flushSync along the way.
* fix: send `$effect.pending` count to the correct boundary
* make boundary.pending private, use boundary.is_pending consistently
* move error to correct place
* we need that error
* update JSDoc