CreateStore

createStore

Creates a reactive store with state, getters, and actions.

Signature

function createStore<S, G, A>(
  name: string,
  options: {
    state: () => S;
    getters?: { [K in keyof G]: (state: S) => G[K] };
    actions?: { [K in keyof A]: (this: StoreInstance<S, G, A>, ...args: any[]) => any };
    persist?: PersistenceConfig<S>;
  }
): StoreInstance<S, G, A>;

Parameters

  • name: A unique string identifier for the store. Must be unique across your application.
  • options:
    • state: A function returning the initial state object.
    • getters (optional): An object of getter functions that compute derived state.
    • actions (optional): An object of action methods that can modify state.
    • persist (optional): Persistence configuration for automatic state saving and restoration.

Returns

A StoreInstance with flattened access to state, getters, and actions.

Example

import { createStore, LocalStorageAdapter } from '@quantajs/core';

const store = createStore('counter', {
  state: () => ({ count: 0 }),
  getters: { 
    doubled: (state) => state.count * 2 
  },
  actions: { 
    increment() { this.count++; } 
  },
  persist: {
    adapter: new LocalStorageAdapter('counter-store'),
    debounceMs: 500
  }
});

console.log(store.count); // 0 (or restored value from storage)
console.log(store.doubled); // 0 (or restored value * 2)
store.increment();
console.log(store.count); // 1
console.log(store.doubled); // 2

// State is automatically saved to localStorage and restored on page reload

Store Structure

The returned store instance provides:

  • State Properties: Direct access to all state properties
  • Getters: Computed values that automatically update when dependencies change
  • Actions: Methods that can modify state using this
  • subscribe: Method to subscribe to store changes
  • $reset: Method to reset store to initial state
  • $persist: Persistence manager for manual persistence control (if persistence is configured)
  • $destroy: Method to clean up store resources and remove it from the registry
  • notifyAll: Method to manually notify all subscribers of changes

TypeScript Support

interface CounterState {
  count: number;
  name: string;
}

interface CounterGetters {
  doubled: number;
  greeting: string;
}

interface CounterActions {
  increment(): void;
  decrement(): void;
  setName(name: string): void;
}

const counterStore = createStore<CounterState, CounterGetters, CounterActions>('counter', {
  state: () => ({ count: 0, name: 'Counter' }),
  getters: {
    doubled: (state) => state.count * 2,
    greeting: (state) => `Hello ${state.name}!`,
  },
  actions: {
    increment() { this.count++; },
    decrement() { this.count--; },
    setName(name: string) { this.name = name; },
  },
});

Store Lifecycle Methods

subscribe

Subscribe to store changes:

const store = createStore('counter', {
  state: () => ({ count: 0 }),
});

const unsubscribe = store.subscribe((snapshot) => {
  console.log('Store changed:', snapshot);
});

// Later, unsubscribe
unsubscribe();

$reset

Reset the store to its initial state:

const store = createStore('counter', {
  state: () => ({ count: 0, name: 'Counter' }),
});

store.count = 10;
store.name = 'Updated';

store.$reset(); // Resets to { count: 0, name: 'Counter' }

$destroy

Clean up store resources and remove it from the registry. This is useful when you need to completely remove a store:

const store = createStore('temporary', {
  state: () => ({ data: [] }),
  persist: {
    adapter: new LocalStorageAdapter('temp-store'),
  },
});

// Use the store...

// When done, clean up
store.$destroy(); // Removes store, clears subscribers, destroys persistence

Note: After calling $destroy(), the store should no longer be used. Attempting to use it may result in errors.

notifyAll

Manually notify all subscribers of changes. This is typically used internally, but can be useful for advanced scenarios:

const store = createStore('counter', {
  state: () => ({ count: 0 }),
});

store.subscribe(() => {
  console.log('Store updated');
});

// Manually trigger notification
store.notifyAll(); // All subscribers are notified

Store Lifecycle Management

Creating and Destroying Stores

// Create a store
const userStore = createStore('user', {
  state: () => ({ user: null }),
  persist: {
    adapter: new LocalStorageAdapter('user-store'),
  },
});

// Use the store throughout your application
function login(user) {
  userStore.user = user;
}

// When the store is no longer needed (e.g., logout, cleanup)
function cleanup() {
  userStore.$destroy(); // Clean up resources
}

Multiple Store Management

// Create multiple stores
const stores = {
  user: createStore('user', {
    state: () => ({ user: null }),
  }),
  cart: createStore('cart', {
    state: () => ({ items: [] }),
  }),
  settings: createStore('settings', {
    state: () => ({ theme: 'light' }),
  }),
};

// Clean up all stores when needed
function cleanupAllStores() {
  Object.values(stores).forEach(store => {
    store.$destroy();
  });
}

React Integration with Cleanup

import { useEffect } from 'react';
import { useCreateStore } from '@quantajs/react';

function Component() {
  const store = useCreateStore('component-store', () => ({ data: [] }));
  
  useEffect(() => {
    // Store is automatically cleaned up when component unmounts
    // But you can manually clean up if needed
    return () => {
      store.$destroy();
    };
  }, []);
  
  return <div>{/* Component content */}</div>;
}

Error Handling

  • Duplicate Store Names: Throws an error if a store with the same name already exists
  • Invalid State: State must be a function that returns an object
  • Action Context: Actions must use this to access store properties
  • Destroyed Store: Using a store after $destroy() may result in errors

Learn More