All Projects → w11k → Tydux

w11k / Tydux

Licence: apache-2.0
Type safe state management for web applications

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Tydux

Goes
Go Event Sourcing made easy
Stars: ✭ 144 (+336.36%)
Mutual labels:  cqrs, flux-architecture
Rxloop
rxloop = Redux + redux-observable (Inspired by dva)
Stars: ✭ 44 (+33.33%)
Mutual labels:  rxjs, flux-architecture
react-rxjs-flux
a small library for creating applications based on unidirectional data flow
Stars: ✭ 22 (-33.33%)
Mutual labels:  flux-architecture, rxjs
Cqrslite
A lightweight framework to help creating CQRS and Eventsourcing applications in C#
Stars: ✭ 925 (+2703.03%)
Mutual labels:  cqrs
Platform
Reactive libraries for Angular
Stars: ✭ 7,020 (+21172.73%)
Mutual labels:  rxjs
Rails event store
A Ruby implementation of an Event Store based on Active Record
Stars: ✭ 947 (+2769.7%)
Mutual labels:  cqrs
Factory
The missing, complete example of Domain-Driven Design enterprise application backed by Spring stack
Stars: ✭ 967 (+2830.3%)
Mutual labels:  cqrs
Tanok
Elm Architecture-inspired wrapper for Rx.js+React
Stars: ✭ 22 (-33.33%)
Mutual labels:  rxjs
Swiftea
Bits of the Elm Architecture in Swift for iOS, MacOS and SwiftUI
Stars: ✭ 32 (-3.03%)
Mutual labels:  flux-architecture
Magazine Website Akka
The experiment on the akkadotnet
Stars: ✭ 21 (-36.36%)
Mutual labels:  cqrs
Wolkenkit
wolkenkit is an open-source CQRS and event-sourcing framework based on Node.js, and it supports JavaScript and TypeScript.
Stars: ✭ 880 (+2566.67%)
Mutual labels:  cqrs
Dugong
Minimal State Store Manager for React Apps using RxJS
Stars: ✭ 10 (-69.7%)
Mutual labels:  rxjs
Practical Clean Ddd
A simplified and effortless approach to get started with Domain-driven Design, Clean Architecture, CQRS, and Microservices patterns
Stars: ✭ 28 (-15.15%)
Mutual labels:  cqrs
Nestjs Cqrs Starter
Nestjs-cqrs API
Stars: ✭ 25 (-24.24%)
Mutual labels:  cqrs
Eventhorizon
CQRS/ES toolkit for Go
Stars: ✭ 961 (+2812.12%)
Mutual labels:  cqrs
Proppy
Functional props composition for UI components (React.js & Vue.js)
Stars: ✭ 921 (+2690.91%)
Mutual labels:  rxjs
Mini Rx Store
Lightweight Redux Store based on RxJS
Stars: ✭ 32 (-3.03%)
Mutual labels:  rxjs
Ext Saladict
🥗 All-in-one professional pop-up dictionary and page translator which supports multiple search modes, page translations, new word notebook and PDF selection searching.
Stars: ✭ 8,418 (+25409.09%)
Mutual labels:  rxjs
Front End Stack
Starter kit for building single-page app using React, Redux, RxJS, Reselect, Material UI, Immer, Prettier and Webpack.
Stars: ✭ 11 (-66.67%)
Mutual labels:  rxjs
Django Cqrs
A demo application to show how cqrs can be implemented in Django
Stars: ✭ 21 (-36.36%)
Mutual labels:  cqrs

Build Status npm version

Tydux Logo

Encapsulating State Management Library

Tydux is a state management library implemented in TypeScript with a strong focus on encapsulation, type safety and immutability. It can be used standalone or hook into existing Redux-based (or compatible) application.

The key concepts are:

  • You define your state in designated classes or objects.
  • Only commands are allowed to alter the state. Commands are implemented as classes with methods. Every method defines a valid state transition. Hence, only commands are responsible for the state manipulation.
  • Commands are only accessible within a facade. The facade provides the initial state, a read-only access to the state and a stream to subscribe state changes.
  • While commands provide fine-grained methods for state manipulation, the facades provide more coarse-grained methods. For example, a facade could provide a method to load a todo list from the server. To do so, the facade method would 1. use a command method to clear the current state, 2. load the list from the server and 3. use a command method to update the state with the received list.
  • The facade is responsible for handling async operations (e.g. HTTP calls) and uses the commands to change the state accordingly.
  • Consumers of the facade can access a read-only version of the state or subscribe to state changes via an RxJS Observable.
  • You can have as many facades as you like with each of them containing their own commands and state.

If you know Redux:

Tydux shares the concept of state, actions, reducer and selectors but differs in the way they are implemented:

  • Actions and their reducers are implemented together and are called commands. No more action type string identifier!
  • Only facades can access commands
  • A facade provides a read-only stream of state changes

Key benefits:

  • implement "divide and conquer"
  • type safety
  • enforced immutability
  • class-based API
  • ... which works well with Angular's dependency injection

Installation

Install Tydux and all required peer-dependencies:

npm install @w11k/tydux @w11k/rx-ninja rxjs redux redux-devtools-extension.

Quick Overview Demo

Well will need at least a state, the commands and the facade.

Create the state class:

You can implement the state with a class or a plain JavaScript object. Classes are a bit more convenient but remember that you must not use inheritance and that the class only contains fields.

export class TodoState {
  todos: ToDo[] = [
    {isDone: false, name: 'learn TypeScript'},
    {isDone: true, name: 'buy milk'},
    {isDone: true, name: 'clean house'},
  ]
}

Create the commands:

Commands are grouped within a class and can alter the state via this.state. Only the direct field members of the state object can be changed, not the attributes of nested object.

export class TodoCommands extends Commands<TodoState> {

    clear() {
        this.state.todos = [];
    }
    
    setTodoList(todos: ToDo[]) {
        this.state.todos = todos;
    }
    
    toggleTodo(name: string) {
        this.state.todos = this.state.todos.map(
            it => it.name === name ? {...it, isDone: !it.isDone} : it
        )
    }
    
}

Create the facade:

After we created the state and commands, we combine them within a facade.

export class TodoFacade extends Facade<TodoCommands> {

  constructor() {
    super(
        'todos',                // the 'mount point' within the global state 
        new TodoCommands(),     // commands instance defined above
        new TodoState()         // initial state
    );
  }

  /**
   * in our facade we can do synchronous or asynchronous stuff (action or effect)
   */
  async loadTodoListFromServer() {
    this.commands.clear();
    const list = await fetch("/todos");
    this.commands.setTodoList(list);
  }
  
  /**
   * simple delegate to a command method
   */
  toggleDoneStateOf(t: ToDo) {
    this.commands.toggleToDo(t.name);
  }

}

Bootstrap:

After we created the state, commands and facade, we can bootstrap Tydux.

  1. Create a TyduxStore and provide the global initial state (optional, defaults to {}). Every facade's state is part of this global state.
  2. Register the TyduxStore as global store.
  3. Instantiate the facade(s).
// Create and register the tydux store
const tyduxStore = createTyduxStore();      // 1.
setGlobalStore(tyduxStore);                 // 2.

// instantiate every facade once
const todoFacade = new TodoFacade();        // 3.  

Usage:

// get the current state
const todos: ToDo[] = todoFacade.state.todos;

// subscribe to state changes
todoFacade.subscribe(state => {
    const todos: ToDo[] = state.todos;
});

// call facade methods
todoFacade.loadTodoListFromServer();

Documentation

Patron

❤️ W11K - The Web Engineers

❤️ theCodeCampus - Trainings for Angular and TypeScript

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].