@actioncrew/actionstack
TypeScript icon, indicating that this package has built-in type declarations

3.0.7 • Public • Published

ActionStack V3

ActionStack Logo

Next-generation state management for reactive applications
Built on Streamix for ultimate performance and simplicity

Build Status NPM Version NPM Downloads Bundle Size


✨ Key Features

  • 🧩 Modular Architecture — Feature-based modules with co-located state and logic
  • ⚡ Reactive Streams — Built on Streamix for high-performance reactive updates
  • 🔄 Action Handlers — No reducers needed - sync actions with state logic
  • ⚡ Thunk Support — Built-in async operations via thunks
  • 🔒 Safe Concurrency — Built-in locking and execution control
  • 📦 Dynamic Loading — Load/unload modules at runtime
  • 🎯 Type Safety — Full TypeScript support with intelligent inference
  • 🔌 Redux Ecosystem — Works with existing middlewares from Redux ecosystem

📦 Installation

npm install @actioncrew/actionstack

🚀 Quick Start

import { createStore, createModule, action, thunk, selector } from '@actioncrew/actionstack';

// Actions with built-in state handlers
const increment = action('increment', 
  (state: number, payload: number = 1) => state + payload
);

const reset = action('reset', () => 0);

// Create module
const counterModule = createModule({
  slice: 'counter',
  initialState: 0,
  actions: { increment, reset },
  selectors: {
    count: selector((state: number) => state),
  }
});

// Initialize
const store = createStore();
counterModule.init(store);

// Use actions directly
counterModule.actions.increment(5);  // Counter: 5
counterModule.actions.reset();       // Counter: 0

// Subscribe to changes
counterModule.data$.count().subscribe(count => {
  console.log('Counter:', count);
});

🎯 Real-World Example

interface TodoState {
  todos: Todo[];
  loading: boolean;
}

const addTodo = action('add', 
  (state: TodoState, text: string) => ({
    ...state,
    todos: [...state.todos, { id: Date.now(), text, completed: false }]
  })
);

const setTodos = action('setTodos',
  (state: TodoState, todos: Todo[]) => ({ ...state, todos, loading: false })
);

const setLoading = action('setLoading',
  (state: TodoState, loading: boolean) => ({ ...state, loading })
);

// Thunk using createThunk
const fetchTodos = thunk('fetchTodos', () => 
  (dispatch, getState, dependencies) => {
    todoModule.actions.setLoading(true);
    
    dependencies.todoService.fetchTodos()
      .then(todos => todoModule.actions.setTodos(todos))
      .catch(error => {
        todoModule.actions.setLoading(false);
        console.error('Failed to fetch todos:', error);
      });
  }
);

// Selectors
const selectActiveTodos = selector(
  (state: TodoState) => state.todos.filter(t => !t.completed)
);

// Module with dependencies
const todoModule = createModule({
  slice: 'todos',
  initialState: { todos: [], loading: false },
  actions: { addTodo, setTodos, setLoading, fetchTodos },
  selectors: { selectActiveTodos },
  dependencies: { todoService: new TodoService() }
});

// Usage
todoModule.init(store);
todoModule.actions.fetchTodos();

// Reactive UI updates
todoModule.data$.selectActiveTodos().subscribe(activeTodos => {
  renderTodos(activeTodos);
});

🔄 Advanced Features

Static Module Loading

let store = createStore(mainModule);
store.populate(authModule, uiModule, settingsModule);

Dynamic Module Loading

// Load modules at runtime
const featureModule = createDashboardModule();
featureModule.init(store);

// Unload when no longer needed and clear state
featureModule.destroy(true);

Stream Composition

import { combineLatest, map, filter, eachValueFrom } from '@actioncrew/streamix';

// Combine data from multiple modules
const dashboardData$ = combineLatest([
  userModule.data$.selectCurrentUser(),
  todoModule.data$.selectActiveTodos(),
  notificationModule.data$.selectUnread()
]).pipe(
  map(([user, todos, notifications]) => ({
    user,
    todoCount: todos.length,
    hasNotifications: notifications.length > 0
  }))
);

// React to combined state changes
for await (const data of eachValueFrom(dashboardData$)) {
  updateDashboard(data);
}

Store Configuration

const store = createStore({
  dispatchSystemActions: true,
  awaitStatePropagation: true,
  enableGlobalReducers: false,
  exclusiveActionProcessing: false
}, applyMiddleware(logger, devtools));

🆚 vs Other Solutions

Feature ActionStack V3 Redux + RTK Zustand
Bundle Size Minimal Large Small
Reactivity Built-in Manual Manual
Modules Native Manual Manual
Type Safety Excellent Good Good
Async Actions Native Thunks Manual

📚 Resources


Ready for next-gen state management? 🚀
Install from NPMView on GitHub

Package Sidebar

Install

npm i @actioncrew/actionstack

Weekly Downloads

136

Version

3.0.7

License

MIT

Unpacked Size

180 kB

Total Files

15

Last publish

Collaborators

  • actioncrew