If an even handler is hoisted and said event handler access rest props, we can't be sure whether or not it will access it via `$$props` (optimized) or via `rest()` - therefore we add both as params in this edge case
fixes#12279
* fix: improve ReactiveDate class
* improved test
* added changeset
* improved performance by using less signals
* using the same signal for getX and getUTCX
* fixed types
* combined setX with setUTCX tests together
* simplified fine-grainability by using deriveds
* reused the calculated new_time
* removed logic that reduced number of signals, cuz its use-cases are rare
* inference is fine
* tidy up
* tweaks
* more efficient iteration
* tweak
* more descriptive changeset
* this makes all tests but one pass
* fix
* adjust test to be robust across timezones
* tweak more tests
* Update .changeset/sleepy-dogs-sit.md
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Rich Harris <hello@rich-harris.dev>
* use existing teardown function
* set up stores and unsubscriptions in one go
* we never set last_value, this is gibberish
* simplify
* tidy up
* inline
* more
* only call mark_reactions when updating a source
* move mark_reactions to where it belongs, remove force_schedule stuff
* tweak
* move inspect_effects to where it is used
* this is wrong
* remove obsolete comment
* tweak
* reconnect on get
* try marking unowneds as clean
* tidy up
* tidy up
* simplify
* typo
* don't bother caching length
* fix lint
---------
Co-authored-by: Dominic Gannaway <dg@domgan.com>
* add some explanatory comments
* rename variables
* var
* this appears to be unnecessary?
* more renaming
* surely we only care about array.length?
* no need to cache this, it isnt faster AFAICT
* comment
* remove unnecessary casting
* again
* fix: further avoid duplicate signal dependencies
visitor
another approach
tune
tune
* add test
* clean up test
* early return to reduce indentation, use var over let/const
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
#12202 revealed that TypeScript has a harder time tracing imports when they are indirectly exposed, e.g. `function foo(): void; ... export { foo }` instead of `export function foo(): void;`, which can lead to bugs down the line (such as in that issue). A new `dts-buddy` version fixes this, which in turn fixes#12202
This also adjustes the `Snippet` type and turns it into an interface, which makes for better intellisense: The type will be unpacked in less situations, resulting a more readable and named type.
The refactoring in #12215 didn't take HMR into account. As a result, the anchor was passed to the HMR block, which was subsequently cleaned up on destroy - but the anchor could be shared with other components and therefore needs to stay in the dom. Passing `null` instead solves the problem.
Fixes#12228Fixes#12230Fixes#12233
* fix: deconflict multiple snippets of the same name
* address feedback
* only create BlockStatement when necessary
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* WIP
* progress
* fix
* add comment
* update tests
* mostly fix dynamic elements
* delete unused code
* remove unused code
* more
* tidy up
* fix
* more
* relink effects inside each block
* simpler to just leave these in (without children) and ignore them
* fix head stuff
* tidy up
* fix some type errors
* simplify
* use hydration marker as effect boundary where possible
* all tests passing
* tidy up
* tidy up a bit
* tidy up
* beat typescript into submission
* bring tests over from fix-each-dom-bug
* tweaks
* simplify a tad
* tidy up
* simplify
* reduce indirection
* belt and braces
* tidy
* revert config change
* missed a spot
* regenerate types
* cleaner separation between EachState and EachItem - precursor to efficient relinking
* HMR fix
* set effects
* FINALLY
The media bindings where fragile because the "prevent rerun if update in progress"-logic was flawed: It didn't (re)set the `updating` flag correctly, because it assumed an event and a render effect would always directly follow each other, with one always being first - but that's not true.
It's much more robust to instead compare the value with what's currently present in the DOM. For the very fast-firing current-time-binding a variable is used to not invoke the DOM getter as much, for the others this is not necessary.
Lastly, the playback-rate-binding contained another bug where the listener was setup inside the effect and therefore reinitialized on each binding change - it needs to move into a different effect.
Someone could render a snippet into a custom element, and therefore elements with slot attributes should be allowed within them and be treated as regular elements
closes#12158
Fixes#12166. Turns out that the recent refactors here negated the fact that non-runes mode uses a slightly different source signal that has different equality rules.
I also updated the docs in this PR too to reflect that only plain objects and arrays are proxied.
* Fix memory leak in unmount where document event listeners are not being removed
* changeset
---------
Co-authored-by: Mark Siano <marksiano@Marks-MBP.lan>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Rich Harris <hello@rich-harris.dev>
new dts-buddy makes sure that only the actual public types are exposed (only export { ... } ensures that, for TS historical reasons)
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
* fix: allow multiple optional parameters with defaults
* Apply suggestions from code review
* partial fix
* feat: parse as a whole function
* couple of fixes
* work around acorn-typescript quirks
* add the harder test
* Update .changeset/ten-geese-share.md
---------
Co-authored-by: Rich Harris <hello@rich-harris.dev>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* Ensure binding from legacy component passed to runes component updates correctly. This is done by also using the `prop(..)` variant for a property if it's mutated in runes mode, and then figuring out at runtime whether or not the parent should be notified or not
fixes#12032
* fix adjacent bug around wrong value getting return upon mutation
* deduplicate
* changeset
* simplify
* move comment
* rename
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
make the props parameter optional only when there are no or only optional props
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* fix: wait a microtask for await blocks to reduce UI churn
* fix: wait a microtask for await blocks to reduce UI churn
* fix: wait a microtask for await blocks to reduce UI churn
* fix bug
* Make then blocks reactive
* add test
* update test
* update test
* Update packages/svelte/src/internal/client/dom/blocks/await.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* Add support for catch block
* slightly more specific naming
* if we use the reserved $$ prefix we dont need to mess around with scope.generate
* omit args for then/catch if unnecessary
* neaten up some old code
* shrink code
* simplify test
* add failing test
* preserve pending blocks
* update test
* fix comment typo
* tidy up
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
The `update` function could cause a read, which would end up being tracked in the effect, and said effect would then run multiple times when it should only run once
fixes#11934fixes#12028
* fix: ensure input value is correctly set during hydration
* fix: ensure input value is correctly set during hydration
* address feedback
* fix typos
* early return, var
* fix test
* Update packages/svelte/src/internal/client/dom/elements/attributes.js
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* update changeset
* tweak names
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
prevent misidentification of bindings as delegatable event handlers if used outside event attribute
Fixes#12074
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
add them so that the TypeScript parser doesn't put the following content under the `@deprecated` tag, which messes with the JSON-type-generation script.
When the TypeScript plugin we provide isn't enabled, imports to `.svelte`-files fall back to an ambient module declaration. Said declaration was still only providing the deprecated class. This PR widens the type so that you can also invoke it like a function. After the transition period (Svelte 6 or 7) only the new type should be provided from the module declaration.
* chore: get rid of current_untracking
* simplify
* remove incorrect comment
* only apply unowned check to user effects - less work that way
* tweak
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
The `is` attribute is special and always needs to be part of the static template string, or else it wouldn't be taken into account on initialization
fixes#12052
- give autocompletion for types and more precise event types for html elements
- allow to pass other kinds of event target nodes, like window
closes#12027fixes#12045
* fix: increment derived versions when updating
* we only need to increment version when setting sources and updating deriveds
* no tests fail if we remove this code
* codegolf
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
We need to ensure that if derived a depends on derived b, and a is reconnecting to the dependency graph, that if b was updated more recently than a, a also updates.
Fixes#11988Fixes#12044
follow up to #12014, which wasn't quite the right fix. It would mean that delegated listeners between two manual listeners wouldn't be called at the correct time.
* import Component as Type
interfaces can only be used as a Type, that way it should be imported as type
* fix import type
* regenerate types
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: ensure bound input content is resumed on hydration
* fix: ensure bound input content is resumed on hydration
* Update packages/svelte/src/internal/client/dom/elements/bindings/input.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* fix: ensure bound input content is resumed on hydration
* fix: ensure bound input content is resumed on hydration
* Update packages/svelte/src/internal/client/dom/elements/bindings/input.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* add test
* add test
* add test
* add test
* Update packages/svelte/src/internal/client/dom/elements/bindings/input.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* add test
* add test
* newlines between multi-line blocks, let the code breathe
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* chore: simplify SSR escaping
* treat solo expressions the same as sequence expressions
* reduce some indirection
* more
* tidy
* tidy
* remove unused types
* more
* this doesnt do anything
* more
* Anchor is unused
* simplify
* simplify
* move special case handling
* more
* simplify
* simplify
* simplify
* more
* unnecessary
* simplify
* remove unused arg
* more
* more
* unnecessary
* more
* more
* dedupe
In a handful of places, we're using effect(...) to defer work that only needs to happen once (like autofocusing an element). This is overkill. There is a much cheaper and simpler way that already exists in the codebase — queue_micro_task.
It feels like we could probably use it in more places, but when I tried it causes some tests to fail, likely because of subtle timing issues that don't apply to the things changed in this PR.
* fix: create sources for initial values of Set
* fix: create sources lazily on Set
* fix: avoid creating sources if sizes are the same
* chore: add test for size of Set
* create iterator lazily
* tidy up test
* oops
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
When an event listener is removed right before it would be fired, adding a new listener comes too late for the browser and the event is swallowed.
The fix is to tweak the spread attributes function to keep using the same object for updates so that we can wrap the event listener to invoke it like `attributes[key](evt)` instead.
No test because it seems impossible to reproduce in testing environments.
Fixes#11903
* docs: make legacy.componentApi more visible
People didn't know that this exists, so we should make it more visible through having it be part of the error message, and calling it out in the docs with more details
* clarify
* flesh out message, put error behind a function
* make it work with HMR
* fix
* fix
* this makes it work. i don't fully understand why
* changeset
* changeset
* Delete .changeset/twelve-foxes-press.md
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
The current type narrows the binding type to `""` by default, which means "no bindings on this component". While this is the common case, it makes it very cumbersome to use the `Component` type because legacy components are of type `string` and as soon as you have bindings, the type is something like `"foo" | "bar"` which _also_ is not assignable to `""` which is semantically wrong, because you should be able to assign a component that can have bindings to a type that accepts none.
The pragmatic solution is to change the binding type to allow `string`, which means someone theoretically could use bindings with a component that doesn't have bindings:
```svelte
<script>
let component: Component<{ prop: boolean }> = IAcceptNoBindings;
</script>
<!-- allowed but should be a type error -->
<svelte:component this={component} bind:prop={foo} />
```
But this is a) rare anyway and b) can be caught at runtime
This came up in comments of #11775
* fix: append start/end info to more tags
We should add them everywhere we can
Related https://github.com/sveltejs/language-tools/pull/2385
* changeset
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Also remove create_block function in favor of calling visit which in turn calls the fragment visitor, to ensure scope is updated correctly
Fixes#11450
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Both `<svelte:element this="div">` and `<svelte:element this={"div"}>` were backported as `tag: "div"` for the old AST. That's wrong because the latter should result in `tag: { type: 'Literal', .. }`. Fixing this makes all the tests in prettier-plugin-svelte pass with Svelte 5.
Also cleaned up a bit of code in the parser.
* fix: populate `this.#sources` when constructing reactive map
* populate sources in first #read_all
* use increment helper
* use numbers instead of symbols
* make forEach work
* feat: bind `activeElement` and `pointerLockElement` in `<svelte:document>`
* add test, use focusin/focusout rather than focus/blur
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: silence `state_referenced_locally` when state is exported
* chore: add changesets
* chore: use `some`
* fix
* better
* we don't need a whole new test for this
* Update .changeset/few-zoos-own.md
* prettier
* tidy up the test a bit since we're in here
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Rich Harris <hello@rich-harris.dev>
* fix: keep default values of props a proxy after reassignment
* fix: make this work for non bindable props too
* chore: more comprehensive test
* chore: cast away
* chore: better variable name and check
* chore: fix lint
I noticed that we spend a lot of time dealing with a recursive function when propagating events. Let's avoid that overhead and move back to a much faster while loop. We can also stack the errors and throw them at the end.
Closes#11727.
This PR aims to tackle issues around our reactive Map/Set implementations. Notably:
- We now store the values on the backing Map/Set, allowing for much better introspection in console/dev tools
- We no longer store the values inside the source signals, instead we use Symbols and booleans only as markers
There's one limitation around `.has(x)` when `x` is not in the Map/Set yet - it's not fine-grained. Making it so could create too much memory pressure when e.g. iterating a big list of items with few of them being in the set (`has` returns `false` most of the time).
When a proxy is reassigned, we call `$.proxy` again. There are cases where there's a component context set but the reassignment actually happens for variable that is ownerless within shared state or somewhere else. In that case we get false positives right now. The inverse is also true where reassigning can delete owners (because no component context exists) and result in false negatives. The fix is to pass the previous value in to copy over the owners from it.
Fixes#11525
Fixes#11817.
It turns out that we weren't fully handling the disconnection of derived signals from the reactivity graph – resulting in cases where they could leak memory because they were not being removed from their dependency reactions array. However, removing ourselves from this array meant that any future changes might mean we need to reconnect the derived to the graph again – so we have to do some additional bookkeeping to make this work. Thankfully, we already have versioning because of unowned deriveds, we can use the versions to understand if the owned derived signal is dirty after being connected to the reactivity graph again – something we couldn't do in early permutations of the signal architecture – and likely why we hadn't addressed this in the same sense.
If a property is mutated, the assumption is that it is deeply reactive. In those cases, the fallback value should be proxified so that it also is deeply reactive.
fixes#11425
- the previous assumption was wrong: browser don't fire a scroll event initially when the scroll isn't smooth
- the previous logic wasn't using the "is scrolling now" logic which meant the render effect fired immediately after, causing smooth scrolling to start too late to be overridden
adjusted the comment and reused the scroll handler function to guard against the race condition
fixes#11623
In Svelte 3 and 4, components were classes under the hood, and the base class was `SvelteComponent`. This class was also used in language tools to properly type check the template code.
In Svelte 5, components are functions. To give people a way to extend them programmatically, it would be good to expose the actual shape of components. This is why this PR introduces a new `Component` type.
For backwards compatibility reasons, we can't just get rid of the old class-based types. We also need to ensure that language tools can work with both the new and old types: There are many libraries out there that provide `d.ts` files with type definitions written using the class types - these should not error.
That's why there's an accompagning language tools PR (https://github.com/sveltejs/language-tools/pull/2380) that's doing the heavy lifting: Instead of generating classes, it now generates a constant and an interfaces and uses Typescript's declaration merging feature to provide both so we can declare a component export as being both a class and a function. That ensures that people can still instantiate them with `new` (which they can do if they use the `legacy.componentApi` compiler option), and it also ensure we don't need to adjust any other code generation mechanisms in language tools yet - from a language tools perspective, classes are still the norm. But through exposing the default export as being _also_ callable as a function we can in a future Svelte version, where classes/the Svelte 4 syntax are removed completely, seamlessly switch over to using functions in the code generation, too, and the `d.ts` files generated up until that point will support it because of the dual shape. This way we have both backwards and forwards compatibility.