class Rydux::Store

Attributes

listeners[R]

Public Class Methods

new(reducers) click to toggle source
# File lib/rydux/store.rb, line 5
def initialize(reducers)
  @state, @listeners = {}, []
  @reducers = strap_reducers(reducers)
end

Public Instance Methods

abandon(listener) click to toggle source

Unsubscribes a listener from the store

# File lib/rydux/store.rb, line 23
def abandon(listener)
  @listeners.delete_if {|l| l[:obj] == listener }
end
dispatch(*args) click to toggle source

Dispatches an action to all reducers. Can be called any of the following ways: Takes in an action and an optional callback proc, which will be called after the dispatch is finished. The action can be passed in either as a hash or as two seperate arguments. E.g. dispatch({ type: 'SOME_ACTION', payload: { key: 'value' } }) is the same as dispatch('SOME_ACTION', { key: 'value' }) Here's an example with a proc: dispatch('SOME_ACTION', { key: 'value' }, ->{ puts “The dispatch is done” })

# File lib/rydux/store.rb, line 34
def dispatch(*args)
  if args.first.is_a? Hash
    _dispatch(args.first, args[1])
  else
    if args[1].is_a? Proc
      _dispatch({ type: args.first }, args[1])
    else
      _dispatch({ type: args.first, payload: args[1] }, args[2])
    end
  end
end
state() click to toggle source

Return a clone of the current state so that the user cannot directly modify state, and introduce side effects

# File lib/rydux/store.rb, line 48
def state
  State.new(@state)
end
subscribe(caller = nil, &block) click to toggle source

Allow subscribing either by passing a reference to self or by passing a block which defines the state keys that this listener cares about

# File lib/rydux/store.rb, line 13
def subscribe(caller = nil, &block)
  if block_given?
    notify_when = block.call(state)
    @listeners << { obj: block.binding.receiver, notify_when: notify_when }
  else
    @listeners << { obj: caller }
  end
end

Private Instance Methods

_dispatch(action, callback = ->{} click to toggle source
# File lib/rydux/store.rb, line 54
def _dispatch(action, callback = ->{})
  @reducers.each {|k, reducer| set_state *[k, reducer.map_state(action, state[k])] }
  callback.call if callback
end
notify_listeners(state_key) click to toggle source
# File lib/rydux/store.rb, line 81
def notify_listeners(state_key)
  @listeners.each do |listener|
    # If no notify_when, the user wants ALL state notifications
    # Otherwise, only send the state notifications they've subscribed to.
    if !listener[:notify_when] && listener[:obj].respond_to?(:state_changed)
      listener[:obj].public_send(:state_changed, state)
    elsif listener[:notify_when].include?(state_key) && listener[:obj].respond_to?(:state_changed)
      listener[:obj].public_send(:state_changed, State.new(state[state_key]))
    end
  end
end
set_state(k, v) click to toggle source

Argument 1 should always be the key within state that we're mutating Argument 2 should be the actual state object

# File lib/rydux/store.rb, line 67
def set_state(k, v)
  if @state[k] != v # Only set state if it has actually changed
    @state[k] = v

    if !self.methods.include? k
      self.define_singleton_method(k.to_sym) do
        return State.new(@state[k])
      end
    end

    notify_listeners(k)
  end
end
strap_reducers(reducers) click to toggle source

Initialize state with the key-value pair associated with each reducer

# File lib/rydux/store.rb, line 60
def strap_reducers(reducers)
  reducers.each {|k, reducer| set_state *[k, reducer.map_state(type: nil)]}
  reducers
end