Store Plugin
Version: 1.2.0
Type: State Management Plugin
Bundle Size: ~6KB minified (~2KB gzipped)
Dependencies: Eleva core (Signal system)
The Store plugin provides centralized, reactive state management for Eleva applications. It enables sharing data across the entire application with automatic UI updates, action-based mutations, namespace organization, and built-in persistence.
Prerequisites
Before using the Store Plugin, you should be familiar with:
TL;DR - Quick Reference
30-Second Setup
// file: app.js
import Eleva from " eleva " ;
import { Store } from " eleva/plugins " ;
const app = new Eleva ( " MyApp " );
app . use ( Store , {
state : { count : 0 },
actions : {
increment : ( state ) => state . count . value ++
}
});
app . component ( " Counter " , {
setup ({ store }) {
return {
count : store . state . count ,
increment : () => store . dispatch ( " increment " )
};
},
template : ( ctx ) => `
<button @click="increment">Count: ${ ctx . count . value } </button>
`
});
app . mount ( document . getElementById ( " app " ), " Counter " );
// Result: Button showing "Count: 0", increments on click
API Cheatsheet
In components (ctx.store):
Method
Description
Returns
store.state
Reactive state object
Object<Signal>
store.dispatch(action, payload?)
Execute an action
Promise<any>
store.subscribe(callback)
Listen to all mutations
() => void
store.getState()
Get non-reactive snapshot (filtered by persistence config)
Object
store.registerModule(name, module)
Add dynamic module
void
store.unregisterModule(name)
Remove module
void
store.createState(key, value)
Add state property
Signal
store.createAction(name, fn)
Add action
void
store.signal
Signal class (use with new)
Class
App instance only (app.store):
Method
Description
Returns
store.replaceState(newState)
Replace state (filtered by persistence config)
void
store.clearPersistedState()
Clear storage
void
State Access Patterns
Pattern
Example
Read state
store.state.count.value
In template
${ctx.count.value}
Namespaced state
store.state.auth.user.value
Dispatch action
store.dispatch("increment")
Dispatch with payload
store.dispatch("setUser", { name: "John" })
Namespaced action
store.dispatch("auth.login", credentials)
Configuration Quick Reference
app . use ( Store , {
state : { /* initial state */ },
actions : { /* action functions */ },
namespaces : { /* organized modules */ },
persistence : {
enabled : true ,
key : " app-store " ,
storage : " localStorage " , // or "sessionStorage"
include : [ " theme " ], // only persist these
exclude : [ " tempData " ] // don't persist these
},
devTools : true ,
onError : ( error , context ) => console . error ( error )
});
Template Context: Use ${ctx.count.value} in templates, but @click="increment" for events (no ctx.).
Documentation
Section
Description
Core Concepts
State, actions, and namespaces
Configuration
Options, persistence, and DevTools
Usage Patterns
Counter, todo list, auth, shopping cart
Advanced
Dynamic modules, async patterns, complex state
API Reference
Complete API, TypeScript, troubleshooting
Features
Feature
Description
Reactive State
State wrapped in Signals for automatic UI updates
Action-Based Mutations
Predictable state changes with dispatch
Namespace Organization
Modular state for large applications
Built-in Persistence
Automatic localStorage/sessionStorage sync
Async Support
Native async/await in actions
Subscriptions
Listen to all state mutations
Dynamic Modules
Register/unregister modules at runtime
Emitter Events
store:* events via eleva.emitter for cross-plugin observability
DevTools Integration
Debug state changes in development
TypeScript Support
Full type definitions included
Installation
Via npm
// ESM
import Eleva from " eleva " ;
import { Store } from " eleva/plugins " ;
// or individual import
import { Store } from " eleva/plugins/store " ;
Via CDN
<!-- Option 1: Bundled plugins -->
<script src= "https://cdn.jsdelivr.net/npm/eleva" ></script>
<script src= "https://cdn.jsdelivr.net/npm/eleva/dist/eleva-plugins.umd.min.js" ></script>
<script>
const app = new Eleva ( " MyApp " );
app . use ( ElevaPlugins . Store , { /* options */ });
</script>
<!-- Option 2: Individual plugin -->
<script src= "https://cdn.jsdelivr.net/npm/eleva" ></script>
<script src= "https://cdn.jsdelivr.net/npm/eleva/dist/plugins/store.umd.min.js" ></script>
<script>
const app = new Eleva ( " MyApp " );
app . use ( ElevaStore , { /* options */ });
</script>
Basic Setup
// file: main.js
import Eleva from " eleva " ;
import { Store } from " eleva/plugins " ;
const app = new Eleva ( " MyApp " );
// Install with initial state and actions
app . use ( Store , {
state : {
theme : " light " ,
user : null ,
counter : 0
},
actions : {
setTheme : ( state , theme ) => state . theme . value = theme ,
setUser : ( state , user ) => state . user . value = user ,
increment : ( state ) => state . counter . value ++ ,
decrement : ( state ) => state . counter . value --
}
});
Quick Start Example
import Eleva from " eleva " ;
import { Store } from " eleva/plugins " ;
const app = new Eleva ( " CounterApp " );
app . use ( Store , {
state : { count : 0 },
actions : {
increment : ( state ) => state . count . value ++ ,
decrement : ( state ) => state . count . value -- ,
reset : ( state ) => state . count . value = 0 ,
setCount : ( state , value ) => state . count . value = value
}
});
app . component ( " Counter " , {
setup ({ store }) {
return {
count : store . state . count ,
increment : () => store . dispatch ( " increment " ),
decrement : () => store . dispatch ( " decrement " ),
reset : () => store . dispatch ( " reset " )
};
},
template : ( ctx ) => `
<div class="counter">
<h2>Count: ${ ctx . count . value } </h2>
<button @click="decrement">-</button>
<button @click="reset">Reset</button>
<button @click="increment">+</button>
</div>
`
});
app . mount ( document . getElementById ( " app " ), " Counter " );
// Result: Interactive counter with increment, decrement, and reset
Data Flow
┌─────────────────────────────────────────────────────────────────┐
│ STORE DATA FLOW │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Component │ │ Component │ │ Component │ │
│ │ A │ │ B │ │ C │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ │ store.dispatch("action", payload) │ │
│ └──────────────────┬──────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ STORE │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ Actions │ │ │
│ │ │ increment: (state) => state.count.value++ │ │ │
│ │ └────────────────────┬────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ State │ │ │
│ │ │ count: Signal(0) │ │ │
│ │ │ user: Signal(null) │ │ │
│ │ └────────────────────┬────────────────────────────┘ │ │
│ │ │ Signal notifies watchers │ │
│ │ ▼ │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ Subscribers │ │ │
│ │ │ - Logging, Analytics, Persistence │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────┼──────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Component │ │ Component │ │ Component │ │
│ │ A (update) │ │ B (update) │ │ C (update) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Flow Description
Component dispatches action → store.dispatch("action", payload)
Store executes action → Action function mutates state signals
State signals notify → All watching components are notified
Subscribers called → Logging, analytics, persistence run
Components re-render → Only affected components update
Persistence saves → If enabled, state is saved to storage
Next Steps