svelte-slash-state

Svelte Slash State

A library aiming to fully replace the `svelte/store` module using runes.

svelte-slash-state

Library aimed to fully replace the svelte/store module using runes.

This library will remain to be maintained until velte with provide a built in solution (which I expect to happen).

Credits to Karim for showcasing a startstopnotifier implementation using $effect, here is the repl.

Why?

Shared state

To pass around state (context, props, functions, etc) you need to reference $state in a closure, $state by default only proxies objects meaning only objects will be allowed to be passed around. The State class adds a closure by adding the value property, this allows any primitive to also be passed around without losing the reference to the underlying $state.

Start stop notifier

svelte/store has a powerful feature called the start stop notifier, learn more about it by reading through the svelte/store docs, $state doesn't have any implementation simular to this, again the State class allows us to still use this powerful feature.

Fine grained reactivity

svelte/store allows you to store big objects but those aren't fine grained, meaning when I update $store.a, $store.b also triggers as an update. The State class uses $state which uses a proxy on objects meaning we get fine grained reactivity.

Verbosity

As you will see in the examples under Replacing store, the State class allows for less and easier to reason about code to be written.

Replacing stores

Importing

- import { writable } from 'svelte/store';

+ import { State } from 'svelte-slash-state';

Creating

- const store = writable();

+ const store = new State();
- const store = writable(0);

+ const store = new State(0);
- const store = writable(0, (set, update) => {
-    const interval = setInterval(() => {
-        update((value) => {
-           value++;
-           return value;
-        });
-    }, 1000);
-    return () => clearInterval(interval)
- });

+ const store = new State(0, (store) => {
+    const interval = setInteral(() => {
+        store.value++;
+    }, 1000);
+    return () => clearInterval(interval)
+ });

Reading

- let value;
- store.subscribe((newValue) => (value = newValue));

+ store.value;
- $store;

+ store.value;
- get(store);

+ store.value;

Writing

- store.set(5);

+ store.value = 5;
- store.update((value) => {
-     value++;
-     return value;
- });

+ store.value++;

But where is X?

Readable

readable is merely a wrapper around writable returning only the subscribe method, I don't think this adds any value to the library so I decided to leave this out, this can still easily be achieved if you wish to do so though:

function readable(init, start) {
    const store = new State(init, start);
    return {
        get value() {
            return store.value;
        }
    };
}

Derived

derived is a powerful function to derive a value from one or multiple stores. This function is not included because the $derived rune already solves this for us, for example:

const storeA = new State(5);

const storeB = new State(10);

const sum = $derived(storeA.value + storeB.value);

console.log(sum); // 15

storeA.value++;

console.log(sum); // 16

Get

get is a dirty way to grab a stores value outside a .svelte file by subscribing, grabbing the value and unsubscribing. This function is not included because with $state we can already grab the value without needing a subscription of any sort by simply accessing store.value

But I don't like classes

For the people that really dislike classes there is also a createState function exported, it is identical to new State.

Top categories

Loading Svelte Themes