set.js

import {
	keysToPath,
	keysToPathChildren
} from './utils';

/**
 * @module set
 */

/**
 * Once fully applied, this returns a new [tree] containing the new node [value] at the location determined by [keys].
 * If an equivalent node already exists in this [tree] it will be replaced.
 * If any [keys] do not exist, a new Immutable Map will be created at the missing key.
 *
 * Be aware that by setting values on deep nodes that don't yet exist,
 * this may cause Maps to be created for child Iterables where other Iterables may be used for children elsewhere in the tree.
 * This will be addressed in a future release.
 *
 * When no childPath is provided then this is functionally equivalent to Immutable's setIn function.
 *
 * @param {Array|List} keys An {Array} or {List} of keys used to identify a node to set.
 * @param value The value to set the node to.
 * @param {Array|List} [childPath=null] An {Array} or {List} of the key path to each node's children.
 * @return {inputFunction} A partially applied function which accepts a single tree interable, and returns the modified iterable.
 */

function deepSet(keys, value, childPath) {
  return (tree) => tree.setIn(keysToPath(keys, childPath), value);
}

/**
 * Once fully applied, this returns a new tree where the children of the node at [keys] are set to [value].
 * If no node exists at [keys] then an Immutable Map will be created at that location.
 * When no childPath is provided then this is functionally equivalent to Immutable's setIn function.
 *
 * @param {Array|List} keys An {Array} or {List} of keys used to identify a node to set.
 * @param value The value to set the node to.
 * @param {Array|List} [childPath=null] An {Array} or {List} of the key path to each node's children.
 * @return {inputFunction} A partially applied function which accepts a single tree interable, and returns the modified iterable.
 */

function deepSetChildren(keys, value, childPath) {
  return (tree) => tree.setIn(keysToPathChildren(keys, childPath), value);
}

export {
  deepSet,
  deepSetChildren
}