# 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)
        }
      }
    })