or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

actions.mdcompiler.mdcore-runtime.mdeasing-functions.mdindex.mdlist-animations.mdmotion-animation.mdstore-management.mdtransitions.md
tile.json

store-management.mddocs/

Store Management

Reactive state management system with readable, writable, and derived stores for application-wide state.

Capabilities

Writable Stores

Create stores that can be read from and written to by any part of your application.

/**
 * Creates a writable store that allows both updating and reading by subscription
 * @param value - Initial value
 * @param start - Optional start/stop notifier function
 * @returns Writable store instance
 */
function writable<T>(value?: T, start?: StartStopNotifier<T>): Writable<T>;

interface Writable<T> extends Readable<T> {
  /** Set value and inform subscribers */
  set(this: void, value: T): void;
  /** Update value using callback and inform subscribers */
  update(this: void, updater: Updater<T>): void;
}

interface Readable<T> {
  /** Subscribe to value changes */
  subscribe(this: void, run: Subscriber<T>, invalidate?: Invalidator<T>): Unsubscriber;
}

type Subscriber<T> = (value: T) => void;
type Unsubscriber = () => void;
type Updater<T> = (value: T) => T;
type Invalidator<T> = (value?: T) => void;

Usage Examples:

import { writable } from "svelte/store";

// Basic writable store
const count = writable(0);

// Subscribe to changes
const unsubscribe = count.subscribe(value => {
  console.log('Count is now:', value);
});

// Update the store
count.set(5);
count.update(n => n + 1);

// Clean up subscription
unsubscribe();

// Store with start/stop logic
const websocketStore = writable(null, (set) => {
  const socket = new WebSocket('ws://localhost:8080');
  
  socket.onmessage = (event) => {
    set(JSON.parse(event.data));
  };
  
  return () => {
    socket.close();
  };
});

Readable Stores

Create read-only stores that can be subscribed to but not directly modified.

/**
 * Creates a readable store that allows reading by subscription
 * @param value - Initial value
 * @param start - Optional start/stop notifier function
 * @returns Readable store instance
 */
function readable<T>(value?: T, start?: StartStopNotifier<T>): Readable<T>;

type StartStopNotifier<T> = (
  set: (value: T) => void,
  update: (fn: Updater<T>) => void
) => void | (() => void);

Usage Examples:

import { readable } from "svelte/store";

// Time store that updates every second
const time = readable(new Date(), (set) => {
  const interval = setInterval(() => {
    set(new Date());
  }, 1000);
  
  return () => clearInterval(interval);
});

// Mouse position store
const mousePosition = readable({ x: 0, y: 0 }, (set) => {
  const handleMouseMove = (event) => {
    set({ x: event.clientX, y: event.clientY });
  };
  
  document.addEventListener('mousemove', handleMouseMove);
  
  return () => {
    document.removeEventListener('mousemove', handleMouseMove);
  };
});

Derived Stores

Create stores whose values are computed from other stores.

/**
 * Creates a derived store by synchronizing one or more readable stores
 * @param stores - Input stores (single store or array)
 * @param fn - Function to compute derived value
 * @param initial_value - Optional initial value
 * @returns Readable store with derived value
 */
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
): Readable<T>;

function derived<S extends Stores, T>(
  stores: S, 
  fn: (values: StoresValues<S>) => T, 
  initial_value?: T
): Readable<T>;

type Stores = Readable<any> | [Readable<any>, ...Array<Readable<any>>] | Array<Readable<any>>;
type StoresValues<T> = T extends Readable<infer U> ? U : { [K in keyof T]: T[K] extends Readable<infer U> ? U : never };

Usage Examples:

import { writable, derived } from "svelte/store";

const firstName = writable('John');
const lastName = writable('Doe');

// Simple derived store
const fullName = derived(
  [firstName, lastName],
  ([first, last]) => `${first} ${last}`
);

// Derived store with initial value
const greeting = derived(
  fullName,
  ($fullName) => `Hello, ${$fullName}!`,
  'Hello, World!'
);

// Async derived store with set callback
const userProfile = derived(
  userId,
  ($userId, set) => {
    if (!$userId) {
      set(null);
      return;
    }
    
    fetch(`/api/users/${$userId}`)
      .then(res => res.json())
      .then(set);
  },
  null
);

Store Utilities

Utility functions for working with stores.

/**
 * Makes a store readonly
 * @param store - Store to make readonly
 * @returns Readonly version of the store
 */
function readonly<T>(store: Readable<T>): Readable<T>;

/**
 * Gets the current value from a store by subscribing and immediately unsubscribing
 * @param store - Store to get value from
 * @returns Current store value
 */
function get<T>(store: Readable<T>): T;

Usage Examples:

import { writable, readonly, get } from "svelte/store";

const internalStore = writable(42);

// Create readonly version for external use
export const publicStore = readonly(internalStore);

// Get current value without subscribing
const currentValue = get(internalStore);
console.log('Current value:', currentValue);

// Useful in event handlers
function handleClick() {
  const currentCount = get(count);
  console.log('Button clicked, count is:', currentCount);
}

Store Patterns

Common patterns for using stores effectively in Svelte applications.

Custom Store Pattern:

import { writable } from "svelte/store";

function createCounter() {
  const { subscribe, set, update } = writable(0);
  
  return {
    subscribe,
    increment: () => update(n => n + 1),
    decrement: () => update(n => n - 1),
    reset: () => set(0)
  };
}

export const counter = createCounter();

Store with Validation:

import { writable } from "svelte/store";

function createValidatedStore(initialValue, validator) {
  const { subscribe, set } = writable(initialValue);
  
  return {
    subscribe,
    set: (value) => {
      if (validator(value)) {
        set(value);
      } else {
        throw new Error('Invalid value');
      }
    }
  };
}

const email = createValidatedStore('', (value) => {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
});

Local Storage Store:

import { writable } from "svelte/store";

function createLocalStorageStore(key, initialValue) {
  const storedValue = localStorage.getItem(key);
  const store = writable(storedValue ? JSON.parse(storedValue) : initialValue);
  
  return {
    subscribe: store.subscribe,
    set: (value) => {
      localStorage.setItem(key, JSON.stringify(value));
      store.set(value);
    },
    update: (callback) => {
      store.update((value) => {
        const newValue = callback(value);
        localStorage.setItem(key, JSON.stringify(newValue));
        return newValue;
      });
    }
  };
}

const settings = createLocalStorageStore('app-settings', { theme: 'light' });