Alveron Middleware Persistence
raw JSON →Alveron Middleware Persistence is a specialized middleware designed to integrate a state persistence layer into Alveron applications. Alveron is a lightweight, Elm-inspired state management library for React (approx. 1.2kb) that leverages React's `useState` hook and handles asynchronous side effects. This middleware enables Alveron stores to automatically persist their state to browser storage mechanisms like `localStorage` or `sessionStorage`, ensuring that application data endures across page reloads or browser sessions. The current stable version, 8.0.3, is designed to work seamlessly with Alveron versions greater than 8.0.0. While a specific release cadence for this middleware is not publicly documented, its versioning typically aligns with major releases of the core `alveron` library. Its primary differentiator is its direct compatibility and integration within the Alveron ecosystem, providing a structured approach to state hydration and rehydration tailored for Alveron's model, actions, and effects architecture.
Common errors
error Uncaught TypeError: Cannot read properties of undefined (reading 'getItem') ↓
typeof window !== 'undefined' or provide localStorage / sessionStorage polyfills for Node.js environments. error TypeError: (0 , _alveron_middleware_persistence__WEBPACK_IMPORTED_MODULE_1__.default) is not a function ↓
import persistenceMiddleware from 'alveron-middleware-persistence';. For CommonJS (if supported), ensure correct interop or use a bundler that handles ESM imports correctly. error Error: Alveron: useStoreWithMiddleware expects the 'alveron' library to be installed. Please ensure it's in your dependencies. ↓
npm install alveron@'>8.0.0' or yarn add alveron@'>8.0.0'. Warnings
breaking Major version updates (e.g., from v7 to v8) typically introduce breaking changes, often related to underlying Alveron API changes or persistence configuration format. Consult Alveron's changelog and this middleware's documentation for migration steps. ↓
gotcha Changes to the shape of your persisted state (e.g., adding/removing properties, changing data types) can lead to hydration errors or unexpected behavior if old, incompatible data exists in `localStorage` or `sessionStorage`. Users' browsers might hold stale data from previous versions of your application. ↓
gotcha This middleware is designed for browser environments using `localStorage` or `sessionStorage`. Attempting to use it directly in a Node.js environment (e.g., for Server-Side Rendering) without appropriate polyfills for these browser APIs will result in runtime errors. ↓
Install
npm install alveron-middleware-persistence yarn add alveron-middleware-persistence pnpm add alveron-middleware-persistence Imports
- persistenceMiddleware wrong
const persistenceMiddleware = require('alveron-middleware-persistence');correctimport persistenceMiddleware from 'alveron-middleware-persistence'; - PersistenceConfig
import persistenceMiddleware, { PersistenceConfig } from 'alveron-middleware-persistence';
Quickstart
import * as React from 'react';
import { useStoreWithMiddleware, Middleware } from 'alveron';
import persistenceMiddleware from 'alveron-middleware-persistence';
interface Model {
count: number;
lastUpdate: string;
}
interface Actions {
increment: (amount?: number) => Model;
decrement: (amount?: number) => Model;
}
const initialModel: Model = {
count: 0,
lastUpdate: new Date().toISOString(),
};
const actions = {
increment: (amount: number = 1) => (prevState: Model) => [
{ ...prevState, count: prevState.count + amount, lastUpdate: new Date().toISOString() },
],
decrement: (amount: number = 1) => (prevState: Model) => [
{ ...prevState, count: prevState.count - amount, lastUpdate: new Date().toISOString() },
],
};
// Define persistence configuration
const persistenceConfig = {
key: 'my-alveron-app-state', // Unique key for localStorage
storage: localStorage, // or sessionStorage
// Optional: only persist `count`, not `lastUpdate`
partialize: (state: Model) => ({ count: state.count }),
};
const persistedCounterMiddleware: Middleware<Model, Actions> = persistenceMiddleware(persistenceConfig);
function Counter() {
const [state, { increment, decrement }] = useStoreWithMiddleware(
actions,
initialModel,
[persistedCounterMiddleware]
);
return (
<div>
<h1>Count: {state.count}</h1>
<p>Last updated: {new Date(state.lastUpdate).toLocaleTimeString()}</p>
<button onClick={() => increment()}>Increment</button>
<button onClick={() => decrement()}>Decrement</button>
<button onClick={() => localStorage.clear()}>Clear Storage</button>
<p>Refresh the page to see the count persist!</p>
</div>
);
}
function App() {
return (
<React.StrictMode>
<Counter />
</React.StrictMode>
);
}
export default App;