delete.js

import {
	deepUpdateChildren
} from './update';

import {
	nodePathToKeys,
	nodePathToKeysChildren
} from './utils';

/**
 * @module delete
 */

/**
 * Once fully applied, this returns a new tree that no longer contains the node at `nodePath`, or any of its child nodes.
 * If there is no node at `nodePath` then no change will occur.
 *
 * When no `childPath` is provided then this is functionally equivalent to Immutable's `deleteIn()` method.
 *
 * @param {NodePath} nodePath A NodePath used to uniquely identify the node to delete.
 * @param {ChildPath} [childPath=null] An `Array` or `List` of keys indicating where to find each node's children from within each node.
 * @return {InputFunction} A partially applied function which accepts a single tree `Iterable`, and returns the modified tree `Iterable`.
 */

function deepDelete(nodePath, childPath=null) {
  return (tree) => tree.deleteIn(nodePathToKeys(nodePath, childPath));
}

/**
 * Once fully applied, this returns a new tree where the children of the node at `nodePath` have been deleted. The child container will still remain.
 * This is the equivalent of calling the following: 
 * ```js
 * deepUpdateChildren(nodePath, kids => kids.clear(), childPath);
 * ```
 * No change will occur if any of the following circumstances are true:
 * - If there is no node at `nodePath`
 * - If `childPath` is provided and the node has no child `Iterable`
 * - If no `childPath` is provided and the node itself is not `Iterable`
 *
 * If no `childPath` is provided and the node is `Iterable`, then this has the same effect as calling `clear()` on the node.
 *
 * @param {NodePath} nodePath A `NodePath` used to uniquely identify a node whose children will be deleted.
 * @param {ChildPath} [childPath=null] An `Array` or `List` of keys indicating where to find each node's children from within each node.
 * @return {InputFunction} A partially applied function which accepts a single tree `Iterable`, and returns the modified tree `Iterable`.
 */

function deepDeleteChildren(nodePath, childPath=null) {
  return (tree) => tree.update(deepUpdateChildren(nodePath, kids => kids == null ? null : kids.clear(), childPath, null));
}

export {
  deepDelete,
  deepDeleteChildren
}