src/cursor.js
function makeSetter(name, typeChecker) {

  /**
   * Binding a setter method to the Cursor class and having the following
   * definition.
   *
   * Note: this is not really possible to make those setters variadic because
   * it would create an impossible polymorphism with path.
   *
   * @todo: perform value validation elsewhere so that tree.update can
   * beneficiate from it.
   *
   * Arity (1):
   * @param  {mixed} value - New value to set at cursor's path.
   *
   * Arity (2):
   * @param  {path}  path  - Subpath to update starting from cursor's.
   * @param  {mixed} value - New value to set.
   *
   * @return {mixed}       - Data at path.
   */
  Cursor.prototype[name] = function(path, value) {

    // We should warn the user if he applies to many arguments to the function
    if (arguments.length > 2)
      throw makeError(`Baobab.Cursor.${name}: too many arguments.`);

    // Handling arities
    if (arguments.length === 1 && !INTRANSITIVE_SETTERS[name]) {
      value = path;
      path = [];
    }

    // Coerce path
    path = coercePath(path);

    // Checking the path's validity
    if (!type.path(path))
      throw makeError(`Baobab.Cursor.${name}: invalid path.`, {path});

    // Checking the value's validity
    if (typeChecker && !typeChecker(value))
      throw makeError(`Baobab.Cursor.${name}: invalid value.`, {path, value});

    // Checking the solvability of the cursor's dynamic path
    if (!this.solvedPath)
      throw makeError(
        `Baobab.Cursor.${name}: the dynamic path of the cursor cannot be solved.`,
        {path: this.path}
      );

    const fullPath = this.solvedPath.concat(path);

    // Filing the update to the tree
    return this.tree.update(
      fullPath,
      {
        type: name,
        value
      }
    );
  };
}
function makeSetter(name, typeChecker) {

  /**
   * Binding a setter method to the Cursor class and having the following
   * definition.
   *
   * Note: this is not really possible to make those setters variadic because
   * it would create an impossible polymorphism with path.
   *
   * @todo: perform value validation elsewhere so that tree.update can
   * beneficiate from it.
   *
   * Arity (1):
   * @param  {mixed} value - New value to set at cursor's path.
   *
   * Arity (2):
   * @param  {path}  path  - Subpath to update starting from cursor's.
   * @param  {mixed} value - New value to set.
   *
   * @return {mixed}       - Data at path.
   */
  Cursor.prototype[name] = function(path, value) {

    // We should warn the user if he applies to many arguments to the function
    if (arguments.length > 2)
      throw makeError(`Baobab.Cursor.${name}: too many arguments.`);

    // Handling arities
    if (arguments.length === 1 && !INTRANSITIVE_SETTERS[name]) {
      value = path;
      path = [];
    }

    // Coerce path
    path = coercePath(path);

    // Checking the path's validity
    if (!type.path(path))
      throw makeError(`Baobab.Cursor.${name}: invalid path.`, {path});

    // Checking the value's validity
    if (typeChecker && !typeChecker(value))
      throw makeError(`Baobab.Cursor.${name}: invalid value.`, {path, value});

    // Checking the solvability of the cursor's dynamic path
    if (!this.solvedPath)
      throw makeError(
        `Baobab.Cursor.${name}: the dynamic path of the cursor cannot be solved.`,
        {path: this.path}
      );

    const fullPath = this.solvedPath.concat(path);

    // Filing the update to the tree
    return this.tree.update(
      fullPath,
      {
        type: name,
        value
      }
    );
  };
}
function makeSetter ( name , typeChecker ) { /**
   * Binding a setter method to the Cursor class and having the following
   * definition.
   *
   * Note: this is not really possible to make those setters variadic because
   * it would create an impossible polymorphism with path.
   *
   * @todo: perform value validation elsewhere so that tree.update can
   * beneficiate from it.
   *
   * Arity (1):
   * @param  {mixed} value - New value to set at cursor's path.
   *
   * Arity (2):
   * @param  {path}  path  - Subpath to update starting from cursor's.
   * @param  {mixed} value - New value to set.
   *
   * @return {mixed}       - Data at path.
   */ Cursor . prototype [ name ] = function ( path , value ) { // We should warn the user if he applies to many arguments to the function if ( arguments . length > 2 ) throw makeError ( ` ${ name } ` ) ; // Handling arities if ( arguments . length === 1 && ! INTRANSITIVE_SETTERS [ name ] ) { value = path ; path = [ ] ; } // Coerce path path = coercePath ( path ) ; // Checking the path's validity if ( ! type . path ( path ) ) throw makeError ( ` ${ name } ` , { path } ) ; // Checking the value's validity if ( typeChecker && ! typeChecker ( value ) ) throw makeError ( ` ${ name } ` , { path , value } ) ; // Checking the solvability of the cursor's dynamic path if ( ! this . solvedPath ) throw makeError ( ` ${ name } ` , { path : this . path } ) ; const fullPath = this . solvedPath . concat ( path ) ; // Filing the update to the tree return this . tree . update ( fullPath , { type : name , value } ) ; } ; }
Function creating a setter method for the Cursor class.

@param {string}   name          - the method's name.
@param {function} [typeChecker] - a function checking that the given value is
valid for the given operation.
Function creating a setter method for the Cursor class .