Skip to content

@breadstone/ziegel-redux ​

MIT LicenseTypeScriptnpm

State management and reactive patterns for the ziegel framework. Provides Redux-style stores, observables, subjects, and action/reducer patterns for predictable state management.

State Management: Redux-inspired state management with reactive programming patterns and type-safe actions and stores.

🚀 Overview ​

@breadstone/ziegel-redux provides:

  • Redux Store: Type-safe Redux store implementation with actions and reducers
  • Reactive Patterns: Observables, subjects, and subscription management
  • Action System: Structured action interfaces and dispatching
  • Middleware Support: Extensible middleware pipeline for actions
  • State Management: Predictable state updates with action/reducer patterns
  • Type Safety: Full TypeScript support for stores, actions, and state

📦 Installation ​

bash
npm install @breadstone/ziegel-redux
# or
yarn add @breadstone/ziegel-redux

🧩 Features & Usage Examples ​

Redux Store ​

typescript
import { Store, IStore, IAction } from '@breadstone/ziegel-redux';

interface AppState {
  count: number;
  user: User | null;
}

interface IncrementAction extends IAction {
  type: 'INCREMENT';
  payload?: number;
}

const store = new Store<AppState&gt;({
  count: 0,
  user: null
});

// Dispatch actions
store.dispatch({ type: 'INCREMENT', payload: 1 });

Observable and Subject ​

typescript
import { Observable, Subject, IObservable, IObserver } from '@breadstone/ziegel-redux';

// Create a subject for data streaming
const dataSubject = new Subject<string&gt;();

// Subscribe to changes
dataSubject.subscribe(value => {
  console.log('Received:', value);
});

// Emit values
dataSubject.next('Hello');
dataSubject.next('World');

// Create custom observables
const customObservable = new Observable&lt;number&gt;(observer =&gt; {
  let count = 0;
  const interval = setInterval(() => {
    observer.next(count++);
  }, 1000);

  return () => clearInterval(interval);
});

Action System ​

typescript
import { IAction, IDispatcher, IReducer } from '@breadstone/ziegel-redux';

// Define typed actions
interface SetUserAction extends IAction {
  type: 'SET_USER';
  payload: User;
}

interface ClearUserAction extends IAction {
  type: 'CLEAR_USER';
}

type UserActions = SetUserAction | ClearUserAction;

// Implement reducer
const userReducer: IReducer&lt;User | null, UserActions&gt; = (state = null, action) => {
  switch (action.type) {
    case 'SET_USER':
      return action.payload;
    case 'CLEAR_USER':
      return null;
    default:
      return state;
  }
};

Middleware ​

typescript
import { IMiddleware, IAction, IStore } from '@breadstone/ziegel-redux';

// Create logging middleware
const loggingMiddleware: IMiddleware = (store, next) => (action) => {
  console.log('Dispatching action:', action);
  const result = next(action);
  console.log('New state:', store.getState());
  return result;
};

// Apply middleware to store
store.use(loggingMiddleware);

Reactive Subscriptions ​

typescript
import { ISubscription, ISubscribable } from '@breadstone/ziegel-redux';

// Subscribe to store changes
const subscription: ISubscription = store.subscribe(state => {
  console.log('State changed:', state);
});

// Unsubscribe when done
subscription.unsubscribe();

// Work with subscribable patterns
function processSubscribable&lt;T&gt;(subscribable: ISubscribable&lt;T&gt;) {
  return subscribable.subscribe(value => {
    // Process the value
    console.log('Processing:', value);
  });
}

📚 Package import points ​

typescript
import {
    // Reactive Interfaces
    IObservable, IObserver, ISubscribable, ISubscriber, ISubscription,

    // Reactive Implementations
    Observable, Subject,

    // Redux Interfaces
    IAction, IDispatcher, IMiddleware, IReducer,

    // Store
    IStore, Store
} from '@breadstone/ziegel-redux';

📚 API Documentation ​

For detailed API documentation, visit: API Docs

  • @breadstone/ziegel-core: Foundation utilities and type definitions
  • redux: Core Redux library
  • reselect: Selector library for Redux

License ​

MIT

Issues ​

Please report bugs and feature requests in the Issue Tracker

// Use entities for collections interface AppState { users: NormalizedState<User>; products: NormalizedState<Product>; orders: NormalizedState<Order>; ui: UIState; }


### Selector Organization

```typescript
// Create a selectors file for each slice
// users/selectors.ts
export const selectUsersState = (state: RootState) => state.users;
export const selectAllUsers = (state: RootState) => state.users.allIds.map(id => state.users.byId[id]);
export const selectUserById = (state: RootState, id: string) => state.users.byId[id];
export const selectUsersLoading = (state: RootState) => state.users.loading;

// Compose selectors for complex queries
export const selectActiveUsers = createSelector(
  [selectAllUsers],
  (users) => users.filter(user => user.isActive)
);

Migration Guide ​

From Plain Redux ​

typescript
// Before (plain Redux)
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';

const increment = () => ({ type: INCREMENT });
const decrement = () => ({ type: DECREMENT });

const counterReducer = (state = 0, action) => {
  switch (action.type) {
    case INCREMENT:
      return state + 1;
    case DECREMENT:
      return state - 1;
    default:
      return state;
  }
};

// After (Ziegel Redux)
import { createAction, createReducer } from '@ziegel/redux';

const increment = createAction('counter/increment');
const decrement = createAction('counter/decrement');

const counterReducer = createReducer(0, (builder) => {
  builder
    .addCase(increment, (state) => state + 1)
    .addCase(decrement, (state) => state - 1);
});

From Redux Toolkit ​

typescript
// RTK code works with minimal changes
import { createSlice } from '@reduxjs/toolkit';

// This works as-is with Ziegel Redux
const userSlice = createSlice({
  name: 'user',
  initialState,
  reducers: {
    setUser: (state, action) => {
      state.current = action.payload;
    }
  }
});

// Enhanced with Ziegel features
const enhancedStore = createZiegelStore({
  reducers: {
    user: userSlice.reducer
  },
  middleware: {
    analytics: true,
    persistence: true
  }
});

API Reference ​

For complete API documentation, see the API Reference.