The svelte/store
module exports functions for creating readable, writable and derived stores.
Keep in mind that you don't have to use these functions to enjoy the reactive $store
syntax in your components. Any object that correctly implements .subscribe
, unsubscribe, and (optionally) .set
is a valid store, and will work both with the special syntax, and with Svelte's built-in derived
stores.
This makes it possible to wrap almost any other reactive state handling library for use in Svelte. Read more about the store contract to see what a correct implementation looks like.
writablepermalink
ts
function writable<T>(value?: T | undefined,start?: StartStopNotifier<T> | undefined): Writable<T>;
Function that creates a store which has values that can be set from 'outside' components. It gets created as an object with additional set
and update
methods.
set
is a method that takes one argument which is the value to be set. The store value gets set to the value of the argument if the store value is not already equal to it.
update
is a method that takes one argument which is a callback. The callback takes the existing store value as its argument and returns the new value to be set to the store.
ts
import {writable } from 'svelte/store';constcount =writable (0);count .subscribe ((value ) => {console .log (value );}); // logs '0'count .set (1); // logs '1'count .update ((n ) =>n + 1); // logs '2'
ts
import {writable } from 'svelte/store';constcount =writable (0);count .subscribe ((value ) => {console .log (value );}); // logs '0'count .set (1); // logs '1'count .update ((n ) =>n + 1); // logs '2'
If a function is passed as the second argument, it will be called when the number of subscribers goes from zero to one (but not from one to two, etc). That function will be passed a set
function which changes the value of the store, and an update
function which works like the update
method on the store, taking a callback to calculate the store's new value from its old value. It must return a stop
function that is called when the subscriber count goes from one to zero.
ts
import {writable } from 'svelte/store';constcount =writable (0, () => {console .log ('got a subscriber');return () =>console .log ('no more subscribers');});count .set (1); // does nothingconstunsubscribe =count .subscribe ((value ) => {console .log (value );}); // logs 'got a subscriber', then '1'unsubscribe (); // logs 'no more subscribers'
ts
import {writable } from 'svelte/store';constcount =writable (0, () => {console .log ('got a subscriber');return () =>console .log ('no more subscribers');});count .set (1); // does nothingconstunsubscribe =count .subscribe ((value ) => {console .log (value );}); // logs 'got a subscriber', then '1'unsubscribe (); // logs 'no more subscribers'
Note that the value of a writable
is lost when it is destroyed, for example when the page is refreshed. However, you can write your own logic to sync the value to for example the localStorage
.
readablepermalink
ts
function readable<T>(value?: T | undefined,start?: StartStopNotifier<T> | undefined): Readable<T>;
Creates a store whose value cannot be set from 'outside', the first argument is the store's initial value, and the second argument to readable
is the same as the second argument to writable
.
ts
import {readable } from 'svelte/store';consttime =readable (newDate (), (set ) => {set (newDate ());constinterval =setInterval (() => {set (newDate ());}, 1000);return () =>clearInterval (interval );});constticktock =readable ('tick', (set ,update ) => {constinterval =setInterval (() => {update ((sound ) => (sound === 'tick' ? 'tock' : 'tick'));}, 1000);return () =>clearInterval (interval );});
derivedpermalink
ts
function derived<S extends Stores, T>(stores: S,fn: (values: StoresValues<S>,set: (value: T) => void,update: (fn: Updater<T>) => void) => Unsubscriber | void,initial_value?: T | undefined): Readable<T>;
ts
function derived<S extends Stores, T>(stores: S,fn: (values: StoresValues<S>) => T,initial_value?: T | undefined): Readable<T>;
Derives a store from one or more other stores. The callback runs initially when the first subscriber subscribes and then whenever the store dependencies change.
In the simplest version, derived
takes a single store, and the callback returns a derived value.
ts
import {derived } from 'svelte/store';constdoubled =derived (a , ($a ) =>$a * 2);
The callback can set a value asynchronously by accepting a second argument, set
, and an optional third argument, update
, calling either or both of them when appropriate.
In this case, you can also pass a third argument to derived
— the initial value of the derived store before set
or update
is first called. If no initial value is specified, the store's initial value will be undefined
.
ts
import {derived } from 'svelte/store';constdelayed =derived (a ,($a ,set ) => {setTimeout (() =>set ($a ), 1000);},2000);constdelayedIncrement =derived (a , ($a ,set ,update ) => {set ($a );setTimeout (() =>update ((x ) =>x + 1), 1000);// every time $a produces a value, this produces two// values, $a immediately and then $a + 1 a second later});
If you return a function from the callback, it will be called when a) the callback runs again, or b) the last subscriber unsubscribes.
ts
import {derived } from 'svelte/store';consttick =derived (frequency ,($frequency ,set ) => {constinterval =setInterval (() => {set (Date .now ());}, 1000 /$frequency );return () => {clearInterval (interval );};},2000);
In both cases, an array of arguments can be passed as the first argument instead of a single store.
ts
import {derived } from 'svelte/store';constsummed =derived ([a ,b ], ([$a ,$b ]) =>$a +$b );constdelayed =derived ([a ,b ], ([$a ,$b ],set ) => {setTimeout (() =>set ($a +$b ), 1000);});
readonlypermalink
ts
function readonly<T>(store: Readable<T>): Readable<T>;
This simple helper function makes a store readonly. You can still subscribe to the changes from the original one using this new readable store.
ts
import {readonly ,writable } from 'svelte/store';constwritableStore =writable (1);constreadableStore =readonly (writableStore );Property 'set' does not exist on type 'Readable<number>'.2339Property 'set' does not exist on type 'Readable<number>'.readableStore .subscribe (console .log );writableStore .set (2); // console: 2readableStore .set (2); // ERROR
getpermalink
ts
function get<T>(store: Readable<T>): T;
Generally, you should read the value of a store by subscribing to it and using the value as it changes over time. Occasionally, you may need to retrieve the value of a store to which you're not subscribed. get
allows you to do so.
This works by creating a subscription, reading the value, then unsubscribing. It's therefore not recommended in hot code paths.
ts
import {get } from 'svelte/store';constvalue =get (store );
Typespermalink
Readablepermalink
Readable interface for subscribing.
ts
interface Readable<T> {…}
ts
subscribe(this: void, run: Subscriber<T>, invalidate?: Invalidator<T>): Unsubscriber;
run
subscription callbackinvalidate
cleanup callback
Subscribe on value changes.
StartStopNotifierpermalink
Start and stop notification callbacks. This function is called when the first subscriber subscribes.
ts
type StartStopNotifier<T> = (set: (value: T) => void,update: (fn: Updater<T>) => void) => void | (() => void);
Subscriberpermalink
Callback to inform of a value updates.
ts
type Subscriber<T> = (value: T) => void;
Unsubscriberpermalink
Unsubscribes from value updates.
ts
type Unsubscriber = () => void;
Updaterpermalink
Callback to update a value.
ts
type Updater<T> = (value: T) => T;
Writablepermalink
Writable interface for both updating and subscribing.
ts
interface Writable<T> extends Readable<T> {…}
ts
set(this: void, value: T): void;
value
to set
Set value and inform subscribers.
ts
update(this: void, updater: Updater<T>): void;
updater
callback
Update value using callback and inform subscribers.