src/cachimo.js
function put(key, value, timeout, callback) {
  // key type is incorrect
  if (typeof key !== 'string' && typeof key !== 'number' && typeof key !== 'boolean') {
    throw new TypeError(`key can be only: string | number | boolean instead of ${typeof key}`);
  }
  // check if key is not NaN
  if (typeof key === 'number' && isNaN(key)) {
    throw new TypeError('key can be only: string | number | boolean instead of NaN');
  }

  // timeout type is incorrect and/or timeout is not positive number
  if (timeout !== undefined && (typeof timeout !== 'number' || isNaN(timeout) || timeout <= 0)) {
    throw new TypeError('timeout should be positive number');
  }

  // callback type is incorrect
  if (callback !== undefined && typeof callback !== 'function') {
    throw new TypeError(`callback should be function instead of ${typeof callback}`);
  }

  // key does exist
  if (has(key)) {
    return false;
  }

  cache.set(key, value);

  // return Promise
  if (timeout !== undefined && callback === undefined) {
    return new Promise((resolve, reject) => {
      const t = setTimeout(() => {
        if (cache.delete(key)) {
          resolve({ key, value, timeout });
        } else {
          reject(new Error(`${key} does not exist`));
        }
      }, timeout);
      timeouts.set(t, () => reject(new Error(`${key} timeout was cleared`)));
    });
  }

  // execute callback
  if (timeout !== undefined && callback !== undefined) {
    const t = setTimeout(() => {
      if (cache.delete(key)) {
        callback(null, key, value, timeout);
      } else {
        callback(new Error(`${key} does not exist`));
      }
    }, timeout);
    timeouts.set(t, () => callback(new Error(`${key} timeout was cleared`)));
  }

  return true;
}
function put(key, value, timeout, callback) {
  // key type is incorrect
  if (typeof key !== 'string' && typeof key !== 'number' && typeof key !== 'boolean') {
    throw new TypeError(`key can be only: string | number | boolean instead of ${typeof key}`);
  }
  // check if key is not NaN
  if (typeof key === 'number' && isNaN(key)) {
    throw new TypeError('key can be only: string | number | boolean instead of NaN');
  }

  // timeout type is incorrect and/or timeout is not positive number
  if (timeout !== undefined && (typeof timeout !== 'number' || isNaN(timeout) || timeout <= 0)) {
    throw new TypeError('timeout should be positive number');
  }

  // callback type is incorrect
  if (callback !== undefined && typeof callback !== 'function') {
    throw new TypeError(`callback should be function instead of ${typeof callback}`);
  }

  // key does exist
  if (has(key)) {
    return false;
  }

  cache.set(key, value);

  // return Promise
  if (timeout !== undefined && callback === undefined) {
    return new Promise((resolve, reject) => {
      const t = setTimeout(() => {
        if (cache.delete(key)) {
          resolve({ key, value, timeout });
        } else {
          reject(new Error(`${key} does not exist`));
        }
      }, timeout);
      timeouts.set(t, () => reject(new Error(`${key} timeout was cleared`)));
    });
  }

  // execute callback
  if (timeout !== undefined && callback !== undefined) {
    const t = setTimeout(() => {
      if (cache.delete(key)) {
        callback(null, key, value, timeout);
      } else {
        callback(new Error(`${key} does not exist`));
      }
    }, timeout);
    timeouts.set(t, () => callback(new Error(`${key} timeout was cleared`)));
  }

  return true;
}
function put ( key , value , timeout , callback ) { // key type is incorrect if ( typeof key !== 'string' && typeof key !== 'number' && typeof key !== 'boolean' ) { throw new TypeError ( ` ${ typeof key } ` ) ; } // check if key is not NaN if ( typeof key === 'number' && isNaN ( key ) ) { throw new TypeError ( 'key can be only: string | number | boolean instead of NaN' ) ; } // timeout type is incorrect and/or timeout is not positive number if ( timeout !== undefined && ( typeof timeout !== 'number' || isNaN ( timeout ) || timeout <= 0 ) ) { throw new TypeError ( 'timeout should be positive number' ) ; } // callback type is incorrect if ( callback !== undefined && typeof callback !== 'function' ) { throw new TypeError ( ` ${ typeof callback } ` ) ; } // key does exist if ( has ( key ) ) { return false ; } cache . set ( key , value ) ; // return Promise if ( timeout !== undefined && callback === undefined ) { return new Promise ( ( resolve , reject ) => { const t = setTimeout ( ( ) => { if ( cache . delete ( key ) ) { resolve ( { key , value , timeout } ) ; } else { reject ( new Error ( ` ${ key } ` ) ) ; } } , timeout ) ; timeouts . set ( t , ( ) => reject ( new Error ( ` ${ key } ` ) ) ) ; } ) ; } // execute callback if ( timeout !== undefined && callback !== undefined ) { const t = setTimeout ( ( ) => { if ( cache . delete ( key ) ) { callback ( null , key , value , timeout ) ; } else { callback ( new Error ( ` ${ key } ` ) ) ; } } , timeout ) ; timeouts . set ( t , ( ) => callback ( new Error ( ` ${ key } ` ) ) ) ; } return true ; }
Stores an element in-memory with specified key and value.

If only `key` and `value` is provided it returns boolean.
true: if element was stored and key doesn't exist.
false: if key does exist.

If additionally only `timeout` is provided it returns Promise.
Element will be deleted after given `timeout` and Promise will be resolved.
Otherwise it will be rejected if element does not exist.

If additionally `timeout` and `callback` is provided it executes given `callback` after given `timeout`.

@param {string | number | boolean} key can be only: `string` | `number` | `boolean`
@param {any} value can be any type
@param {number} timeout after how much time in milliseconds element will be deleted
@param {(err: Error, key: string | number | boolean, value: any, timeout: number)} callback will be executed after given `timeout`

@returns {boolean | Promise<{ key: string | number | boolean, value: any, timeout: number }>} boolean or Promise
Stores an element in - memory with specified key and value .