Fix: SvelteSet's read_methods (forEach, isDisjointFrom, isSubsetOf, isSupersetOf) and set_like_methods (difference, intersection, symmetricDifference, union) operate on an empty underlying Set instead of the actual data stored in #items.

This commit fixes the issue reported at packages/svelte/src/reactivity/set.js:92

**Bug Explanation:**

After the refactoring to make SvelteSet async-safe, the data storage changed:
- **Before:** Data was stored in the underlying Set via `super.add()` in the constructor
- **After:** Data is stored in a reactive `#items` source containing a Set, while `super()` is called without arguments (empty Set)

The `#init()` method creates implementations for `read_methods` and `set_like_methods` by delegating to `Set.prototype` methods. However, the code used `set_proto[method].apply(this, v)` where `this` is the SvelteSet instance. Since SvelteSet extends Set but never adds items to itself (all data is in `#items`), calling these Set methods on `this` operates on an empty Set.

This caused severe bugs:
- `forEach()` would iterate over nothing instead of actual items
- `isSubsetOf()` would always return `true` (empty set is subset of everything)
- `isSupersetOf()` would always return `false` (empty set can't be superset of non-empty)
- `union()` would only return the other set (union with empty set)
- `intersection()` would return empty (intersection with empty set)
- `difference()` would return empty
- `symmetricDifference()` would just return the other set's items

**The Fix:**

Changed `set_proto[method].apply(this, v)` to `set_proto[method].apply(get(this.#items), v)` in both loops.

This ensures the Set methods operate on the actual data stored in `#items` (the reactive Set that contains all the items) rather than the empty underlying Set that the SvelteSet class extends.

The fix maintains reactivity since `get(this.#items)` is still called, establishing the reactive dependency as intended.

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: Rich-Harris <hello@rich-harris.dev>
async-svelte-set
Vercel 1 day ago
parent cfc47b5654
commit fb7f1eeb5d

@ -90,18 +90,16 @@ export class SvelteSet extends Set {
for (const method of read_methods) {
// @ts-ignore
proto[method] = function (...v) {
get(this.#items);
// @ts-ignore
return set_proto[method].apply(this, v);
return set_proto[method].apply(get(this.#items), v);
};
}
for (const method of set_like_methods) {
// @ts-ignore
proto[method] = function (...v) {
get(this.#items);
// @ts-ignore
var set = /** @type {Set<T>} */ (set_proto[method].apply(this, v));
var set = /** @type {Set<T>} */ (set_proto[method].apply(get(this.#items), v));
return new SvelteSet(set);
};
}

Loading…
Cancel
Save