All files / set index.js

100% Statements 35/35
71.43% Branches 10/14
100% Functions 21/21
100% Lines 31/31
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87            15x 11x   4x       14x       1x 2x         1x 1x 7x         2x 5x 1x   1x 5x           2x 2x           1x 1x           1x 1x   2x       1x 1x   3x       2x 2x   5x       2x 2x 1x   1x            
import { buildReducer } from '../lib/buildReducer'
import * as ActionTypes from './actionTypes'
export * from './selectors'
export * from './actions'
 
function sadd(set=[], item){
  if(set.indexOf(item) === -1){
    return [item, ...set]
  }
  return set
}
 
function srem(set=[], item){
  return set.filter(x => x !== item)
}
 
function sunion(sets){
  return sets.reduce((acc, set) => {
    return set.reduce(sadd, acc)
  }, [])
}
 
function sdiff(sets){
  const [ first, ...rest ] = sets
  return first.filter(item =>
    rest.every(set => set.indexOf(item) === -1))
  .reduce(sadd, [])
}
 
function sinter(sets){
  const [ first, ...rest ] = sets
  if(!sets.every(set => set.length)) {
    return []
  }
  return first.filter(item =>
    rest.every(set => set.indexOf(item) > -1))
  .reduce(sadd, [])
}
 
export default buildReducer({}, {
  [ActionTypes.SADD]: (state, action) => {
    const { name, items } = action.payload
    return {
      ...state,
      [name]: items.reduce(sadd, state[name])
    }
  },
  [ActionTypes.SREM]: (state, action) => {
    const { name, items } = action.payload
    return {
      ...state,
      [name]: items.reduce(srem, state[name])
    }
  },
  [ActionTypes.SUNION]: (state, action) => {
    const { sources, target } = action.payload
    return {
      ...state,
      [target]: sunion(sources.map(setName => state[setName] || []))
    }
  },
  [ActionTypes.SDIFF]: (state, action) => {
    const { sources, target } = action.payload
    return {
      ...state,
      [target]: sdiff(sources.map(setName => state[setName] || []))
    }
  },
  [ActionTypes.SINTER]: (state, action) => {
    const { sources, target } = action.payload
    return {
      ...state,
      [target]: sinter(sources.map(setName => state[setName] || []))
    }
  },
  [ActionTypes.SMOVE]: (state, action) => {
    const { source, target, value } = action.payload
    if(!state[source]){
      throw new Error(`SMOVE - source set ${source} does not exist`)
    }
    return {
      ...state,
      [source]: srem(state[source], value),
      [target]: sadd(state[target], value)
    }
  }
})