Comments (6)
The compiler/editor should at least warn when you are updating the non-reactive maps, sets etc. It does that already when you supposedly forgot to declare a variable with $state when you update it somewhere.
I have spent hours debugging a complex app, turned out i refactored out functions that use reactive maps to a seperate file that didn't import them. It is far, far too easy to forget this (and have your code fail silently).
from svelte.
Just to provide some reasoning for why things are the way they are (which isn't to say that they're set in stone):
- It aids discoverability. Without reading the docs in their entirety, you could completely miss
ReactiveSet
et al, whereas if you (perhaps assuming that built-in sets somehow work this way) typenew Set
and are prompted to auto-import fromsvelte/reactivity
, you're more likely to learn about them - It's clearer that the API matches the built-ins
- We have an ambition, not yet written up in public, to add reactive variants of things like
window
(so that you can readwindow.innerWidth
reactively without the indirection of<svelte:window bind:innerWidth={w} />
, even outside components). I'm not sure what that would look like in this world.reactiveWindow
? Kinda ugly!
There are some potential mitigations for the issues you describe. For example we don't have any inline documentation on these classes, and that could easily be fixed:
![image](https://private-user-images.githubusercontent.com/1162160/344139860-3079bda0-7930-43c9-ba06-bb1db9ff6d5d.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk4NTcxNjIsIm5iZiI6MTcxOTg1Njg2MiwicGF0aCI6Ii8xMTYyMTYwLzM0NDEzOTg2MC0zMDc5YmRhMC03OTMwLTQzYzktYmEwNi1iYjFkYjlmZjZkNWQucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDcwMSUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDA3MDFUMTgwMTAyWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MDAyZTlmNDI5OTJmOTgzOGRlNTc5NDkyMTExZmIyZGEzY2JmNDFhNWUxNTBhYjJiYWIxMTY1NWI1ZTNhMmUwOSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.PVaJOmy-T1Yq0E5AZ3tq7cXcr8Yis7cPhzIhxd1O8CQ)
Slightly trickier, due to how the types get generated (methods that have the same signature as the super class get omitted when TS generates the .d.ts file), but we could probably figure out a way to make it work on methods as well:
![image](https://private-user-images.githubusercontent.com/1162160/344140129-524b9785-0f95-4369-b8a5-777cccdfbc15.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk4NTcxNjIsIm5iZiI6MTcxOTg1Njg2MiwicGF0aCI6Ii8xMTYyMTYwLzM0NDE0MDEyOS01MjRiOTc4NS0wZjk1LTQzNjktYjhhNS03NzdjY2NkZmJjMTUucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDcwMSUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDA3MDFUMTgwMTAyWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MzEyNmM5MDJhZjVjOWQ5OWQ5MGI4YzM5ZWM1YmFmZmFjYWM1NWNkNTIxNWI3OTBhMzdhMWY0NjE4NWI4MjU3OSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.KQ032SmeXfteYhetvLK7BVliKoS4AxlMkv5faZWWWUg)
Admittedly you don't get any indication on the instance itself, only its constructor and methods.
It would also be possible to monkey-patch built-ins at dev time so that if you do something like {set.has(x)}
it warns you that you probably wanted to use the reactive Set
rather than the built-in. Of course, that would yield occasional false positives so we would at minimum need a way to opt out:
<!-- svelte-ignore non_reactive_set -->
<p>{set.has(x)}</p>
(Today, svelte-ignore
only controls compiler warnings, but we could make it work with runtime warnings too.)
from svelte.
100% agree. Runes make reactivity more obvious, the classes however do not
from svelte.
Why don’t you just rename it when you import it?
from svelte.
Do you also need to rename the state rune to make it obvious? Its just about understanding reactivity when you quickly ready through the Code. No need to check for an import. The simple let declaration in svelte Files where replaced by runes for this exact reason (and many others)
from svelte.
Thanks for the in-depth reply, I understand better now. I think the point made by @hanszoons is the most important implication of this choice. (I later edited it into the OP) But if monkey-patching in dev to warn on usage could catch all silent errors, I was wrong to say code cannot be moved across modules safely.
My personal preference would be to reduce ambiguity and avoid the headaches of shadowing globals, even with window
, but my opinions have a history of trending the direction Svelte goes. I'm re-exporting for now but I don't want to go against the grain.
Some thoughts:
- is shadowing globals a good practice in the long run?
- do the learning and aesthetic benefits outweigh the costs?
- it feels intrusive to have to write
globalThis.Set
when the reactive class is imported, or care about what's imported when using maps/sets/etc (though I think the downsides of getting it wrong will usually just be a small perf hit, but there's an ick factor - speculating, I think with shadowing we'll see over-use of the reactive collections in non-reactive contexts) - the monkey-patch will add friction for users who choose to alias to silence the warnings unless it's somehow detected or added as an option
- maybe incompatible with runes for other builtins but
$window
looks better thanreactiveWindow
The reactive version is currently assignable to the builtin, but this can be changed by extending the globals with TypeScript, although sometimes you may want the reactive version to be assignable to the builtin, like in helpers:
TypeScript REPL with assignment change
view TypeScript assignment change example
// Pretend this was imported from 'svelte/reactivity':
export class SvelteSet<T> extends Set<T> {
// Existing properties like this make `Set` not assignable to `SvelteSet`:
#sources = new Map();
// Add a conflicting property to make `SvelteSet` not assignable to `Set`.
// @ts-expect-error - this error is silenced because otherwise we couldn't extend the builtin `Set`
readonly [reactive]: true; // comment this out to see the desired errors go away
}
// Extend the global with a conflicting type to make `SvelteSet` not assignable to `Set`:
declare global {
interface Set<T> {
readonly [reactive]: false; // comment this out to see the desired errors go away
}
}
declare const reactive: unique symbol; // one way to "brand" types
export const a = new Set<string>();
export const b = new SvelteSet<string>();
export const b_from_a: SvelteSet<string> = a; // errors as desired without the brand
export const a_from_b: Set<string> = b; // requires the brand to get this error
takes_b(a); // errors as desired without the brand
takes_a(b); // requires the brand to get this error
function takes_a(a: Set<string>): void {}
function takes_b(b: SvelteSet<string>): void {}
This assignment change fixes some problems but causes new ones, like functions that don't care if it's reactive would require casting. There may only be downsides if the monkey-patching catches the same kinds of errors.
(aside: TypeScript 5.5 reports the unalised ReactiveSet
in the error messages, not the exported Set
or locally aliased SvelteSet
, just another tooling quirk to fix or accept - the simple fix is removing Reactive
, but is that desirable?)
from svelte.
Related Issues (20)
- Svelte 5: Components in #if blocks don't trigger their $effect rune HOT 9
- False positive error: rune outside svelte HOT 1
- Bump all dependencies before final release
- Documentation Clarification for Rookies HOT 3
- Svelte 5 (5.0.0-next.167): Upgrading to the latest Svelte 5 breaks SvelteKit routing HOT 9
- Svelte 5: this type of directive is not valid on components HOT 5
- [Svelte 5] `{#if}` block with several reactive children does not re-render properly HOT 12
- Svelte 5 legacy: transition not working with svelte:element
- next.167 breaks <svelte:component> in development mode
- Sveltekit + Svelte 5: Navigating only loads the layout, not the page HOT 2
- Svelte 5: Mutating data in load fn stops page reactivity HOT 4
- Svelte 5: this type of directive is not valid on components HOT 4
- Svelte 5: Inaccurate Error Message HOT 1
- `batch` function to update multiple sources at once HOT 4
- Svelte 5 reporting invalid type error on Svelte 4 component using slot
- Make aria- dependencies optional HOT 9
- Svelte 5: problems unmounting elements from the dom inside an each block HOT 5
- next.168 development mode and component snippets inside loop HOT 5
- next.168 broke unmounting content in my app HOT 5
- Breakpoints cannot be set on certain locations in Svelte generated code in V8 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from svelte.