chore: remove selector api (#9426)

* chore: remove selector api
pull/9427/head
Dominic Gannaway 1 year ago committed by GitHub
parent 17e6c4f834
commit 5768df1300
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
'svelte': patch
---
chore: remove selector api

@ -1254,105 +1254,6 @@ export function set_signal_status(signal, status) {
}
}
/** @template V */
class Selector {
/** @type {Map<V, Set<import('./types.js').Signal>>} */
#consumers_map = new Map();
/** @type {import('./types.js').Signal<V | null>} */
#active_key;
/** @param {V | null} [key] */
constructor(key) {
this.#active_key = source(key || null);
}
get current() {
return get(this.#active_key);
}
/**
* @param {V | null} key
* @returns {void}
*/
set(key) {
const active_key = this.#active_key;
const previous_key = active_key.value;
if (previous_key === key) {
return;
}
set_signal_value(active_key, key);
const consumers_map = this.#consumers_map;
let consumers = map_get(consumers_map, /** @type {V} */ (previous_key));
if (consumers !== undefined) {
this.#update_consumers(consumers);
}
consumers = map_get(consumers_map, /** @type {V} */ (key));
if (consumers !== undefined) {
this.#update_consumers(consumers);
}
}
/**
* @param {Set<import('./types.js').Signal>} consumers
* @returns {void}
*/
#update_consumers(consumers) {
let consumer;
for (consumer of consumers) {
set_signal_status(consumer, DIRTY);
if ((consumer.flags & IS_EFFECT) !== 0) {
schedule_effect(/** @type {import('./types.js').EffectSignal} */ (consumer), false);
} else {
mark_signal_consumers(consumer, DIRTY, true);
}
}
}
/**
* @param {V} key
* @returns {boolean}
*/
is(key) {
const consumers_map = this.#consumers_map;
let consumers = map_get(consumers_map, key);
if (consumers === undefined) {
consumers = new Set();
map_set(consumers_map, key, consumers);
}
const consumer = current_consumer;
const effect = current_effect;
if (effect !== null && consumer !== null && !consumers.has(consumer)) {
consumers.add(consumer);
push_destroy_fn(effect, () => {
const consumers_set = /** @type {Set<import('./types.js').Signal>} */ (consumers);
consumers_set.delete(effect);
if (consumers_set.size === 0) {
map_delete(consumers_map, key);
}
});
}
return this.#active_key.value === key;
}
}
/**
* `selector` allows you to track the currently selected item in a list in a performance optimized manner
* that runs in constant time (O(1)) - this is only noticable for very large lists.
*
* https://svelte-5-preview.vercel.app/docs/functions#selector
* @template Key
* @param {Key | null} [key]
* @returns {Selector<Key>}
*/
export function selector(key) {
return new Selector(key);
}
/**
* @template V
* @param {V | import('./types.js').Signal<V>} val

@ -13,7 +13,6 @@ export {
user_effect,
render_effect,
pre_effect,
selector,
flushSync,
bubble_event,
safe_equal,

@ -255,12 +255,4 @@ export function afterUpdate(fn) {
// TODO bring implementations in here
// (except probably untrack — do we want to expose that, if there's also a rune?)
export {
flushSync,
createRoot,
mount,
tick,
untrack,
onDestroy,
selector
} from '../internal/index.js';
export { flushSync, createRoot, mount, tick, untrack, onDestroy } from '../internal/index.js';

@ -7,7 +7,6 @@ export {
hasContext,
mount,
onDestroy,
selector,
setContext,
tick,
untrack

@ -1,47 +0,0 @@
import { test } from '../../test';
export default test({
html: `
<button>false</button>
<button>false</button>
<button>false</button>
<p></p>
`,
async test({ assert, target }) {
const [b1, b2, b3] = target.querySelectorAll('button');
await b1.click();
assert.htmlEqual(
target.innerHTML,
`
<button>true</button>
<button>false</button>
<button>false</button>
<p>1</p>
`
);
await b3.click();
assert.htmlEqual(
target.innerHTML,
`
<button>false</button>
<button>false</button>
<button>true</button>
<p>3</p>
`
);
await b2.click();
assert.htmlEqual(
target.innerHTML,
`
<button>false</button>
<button>true</button>
<button>false</button>
<p>2</p>
`
);
}
});

@ -1,11 +0,0 @@
<script>
import { selector } from 'svelte';
let array = $state([1, 2, 3]);
let selected = selector();
</script>
{#each array as item}
<button on:click={() => selected.set(item)}>{selected.is(item)}</button>
{/each}
<p>{selected.current}</p>

@ -23,21 +23,3 @@ To prevent something from being treated as an `$effect`/`$derived` dependency, u
</script>
```
## `selector`
`selector` allows you to track the currently selected item in a list in a performance optimized manner that runs in constant time (`O(1)`). With `selector`, you can immediately determine if an item is selected:
```svelte
<script>
import { selector } from 'svelte';
let array = $state([1, 2, 3]);
let selected = selector();
</script>
{#each array as item}
<button on:click={() => selected.set(item)}>{selected.is(item)}</button>
{/each}
<p>{selected.current}</p>
```

Loading…
Cancel
Save