Skip to content

SSSOCPaulCote/gux

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gux

A redux-like state management library written in Go.

Usage

Your state can be as simple as an int or a more complex struct. The Reducer function interface can take any type. It is up to you to create a reducer that does type assertion and for you to write code handling incorrect state types when getting the state.

import (
    "log"
    "time"

    "github.com/SSSOCPaulCote/gux"
)

type (
    ExampleState struct {
        Counter int
    }
)

var (
    initialState = ExampleState{}
    rootReducer gux.Reducer = func(s interface{}, a gux.Action) (interface{}, error) {
        // assert type of s
		oldState, ok := s.(ExampleState)
		if !ok {
			return nil, gux.ErrInvalidStateType
		}
		// switch case action
		switch a.Type {
		case "counter/increment":
			// assert type of payload
			newCnt, ok := a.Payload.(int)
			if !ok {
				return nil, gux.ErrInvalidPayloadType
			}
			oldState.Counter = oldState.Counter+newCnt
			return oldState, nil
		case "counter/decrement":
			// assert type of payload
			newCnt, ok := a.Payload.(int)
			if !ok {
				return nil, gux.ErrInvalidPayloadType
			}
			oldState.Counter = oldState.Counter-newCnt
			return oldState, nil
		default:
			return nil, gux.ErrInvalidAction
		}
    }
    incrementAction = gux.Action{
        Type: "counter/increment",
        Payload: 1,
    }
    decrementAction = gux.Action{
        Type: "counter/decrement",
        Payload: 1,
    }
)

func main() {
    store := gux.CreateStore(initialState, rootReducer)
    quitChan := make(chan struct{})
    defer close(quitChan)
    go func() {
        for i := 0; i < 5; i++ {
            select {
            case <-quitChan:
                return
            default:
                err := store.Dispatch(incrementAction)
                if err != nil {
                    log.Println(err)
                }
                time.Sleep(1 * time.Second)
            }
        }
    }()
    updateChan, unsub := store.Subscribe("name")
    defer unsub(store, "name")
    for {
        select {
        case <-updateChan:
            state := store.GetState()
            cState, ok := state.(ExampleState)
            if !ok {
                log.Println(gux.ErrInvalidStateType)
                return
            }
            log.Printf("Counter: %v\n", cState.Counter)
            if cState.Counter == 3 {
                log.Println("End")
                return
            }
        }
    }
}

You can be subscribed to state updates via chan. The store is responsible for opening and closing these channels. Because this package is quite lightweight, it's easy to spinup stores for different purposes and be only get state change updates for specific state values. Enjoy!

About

A redux-like state management library written in Go

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages