Skip to content
/ slots Public

Tiny state management inspired by Vuex and Redux

Notifications You must be signed in to change notification settings

timsim00/slots

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 

Repository files navigation

Feedback and questions welcome.

Tiny, uni-directional, central state management in 70 lines of code.

This is currently being used in an experimental, framework-less, build-less, lazily-loaded micro-frontend-y, single file web component and module-only app. It's working well.

Reason for being: https://bundlephobia.com/result?p=vuex@3.1.0 Why download (and parse) 3k when you only need 800b?

API

  • constructor({actions, mutators, subscribers, initState, notify, namespace, debug})
  • dispatch(action, payload)
  • mutate(action, payload)
  • subscribe(listener)
  • notify(namespace)
  • import({namespace, actions, initState, mutators, notify})

Usage

// instantiate Slots somehow:
module.default.prototype.createStore = (actions, mutators, subscribers, initialState = {}, notify, namespace, debug) => {
  return new Slots(actions, mutators, subscribers, initialState, notify, namespace, debug)
}
/* app-root component */
connectedCallback() {
  ...
  const {actions, mutators, initState} = this
  this.store = this.createStore({debug: true, namespace: 'app', actions, mutators, initState,
    subscribers: [
      this.persistState
    ]
  })  
}

get actions() {
  return {
    MY_ACTION: ({mutate}, data) => {
      mutate('app:MY_ACTION', data) // just passing through
    }
  }
}

get mutators() {
  // every mutator better return state or there's gonna be trouble
  return {
    MY_ACTION: (state, res) => {
      state.app.stuff = res
      return state
    }
  }
}

get initState() {
  return {
    orgName: 'mystuff.com',
    stuff: {}
  }
}
/* some other module */

constructor() {
  this.app = document.querySelector('app-root')
  this.store = this.app.store.import(this)

  // if this module has a UI, subscribe to state changes:
  this.store.subscribe((state, namespace) => this.render(state, namespace))
}

render(state, namespace) {
  if (namespace === 'other') {
    // UI is just a function of state
  }
}

get namespace() {
  return 'other'
}

get actions() {
  return {
    OTHER_ACTION: ({mutate, dispatch}, term) => {
      const data = {...}
      const someData = {...}
      dispatch('someNamespace:SOME_ACTION', someData)
      this.app.apiRequest(data)
      .then( res => {
        mutate('other:OTHER_ACTION', res)
      })
    }
  }
}

get mutators() {
  return {
    OTHER_ACTION: (state, res) => {
      const modifiedStuff = res.filter(...)
      state.other.otherStuff = modifiedStuff
      return state
    }
  }
}

get initState() {
  return JSON.parse(localStorage.getItem(this.namespace)) ||
  {
    otherStuff: []
  }
}
// dispatch actions from some module, usually actions defined w/in the same module or related component:
this.store = document.querySelector('app-root').store
...
this.store.dispatch('other:OTHER_ACTION')

About

Tiny state management inspired by Vuex and Redux

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published