2.0.0 • Published 5 years ago

two-key-store v2.0.0

Weekly downloads
1
License
UNLICENSED
Repository
-
Last release
5 years ago

Two Key Store

Simple key-value 'store' with 2 hierarchical keys.

Under the hood it just uses plain js objects, and no external dependencies.

No effort is made to protect the types of keys passed in, but constructor() and add() will skip any non-objects.

Target Environment

This was written to be compatible with vanilla nodejs from v8 onwards.

It exposes itself via module.exports. I will assume that if you need CommonJs, ES6 or a browser module loaded, then you already know how to convert as necessary.

Keys

Keys must be:

  • strings
  • numbers other than NaN
  • objects other than null
  • not undefined

Internally, plain objects are used for storage, so the SAME_VALUE_ZERO logic will apply when comparing keys.

Install

$ npm install --save two-key-store

Usage

Import

const TwoKeyStore = require('two-key-store');

Constructor

const twoKeyStore = new TwoKeyStore();

You can also pass an object to bootstrap the store. See the add() method for details.

const twoKeyStore = new TwoKeyStore({...});

API

set(k1, k2, entity)

Sets the entity at nested key [k1, k2].

An error will be thrown if either k1 or k2 are invalid keys.

const twoKeyStore = new TwoKeyStore();
// empty

twoKeyStore.set('a', 'b', 1);
// ['a', 'b']: 1


twoKeyStore.set('a', 'c', 'anything');
// ['a', 'b']: 1
// ['a', 'c']: 'anything'
  
twoKeyStore.set('d', 'e', [])
// ['a', 'b']: 1 
// ['a', 'c']: anything 
// ['d', 'e']: []

twoKeyStore.set('a', 'b', 'not 1');
// ['a', 'b']: 'not 1'
// ['a', 'c']: 'anything'
// ['d', 'e']: []

add(object)

Adds all the data that can be found, ie entities which are values of objects which are themselves values of the passed in object.

Any keys in the passed-in object which are deemed invalid will simply be ignored.

const twoKeyStore = new TwoKeyStore();
// empty

twoKeyStore.add({
  a: 1, // will be ignored
  b: {
    c: 2,
    d: 3,    
  },
  e: {
    f: {
      g: 4,
      h: 5
    }
  }  
});
// ['b', 'c']: 2
// ['b', 'd']: 3
// ['e', 'f']: {g: 4, h: 5}

twoKeyStore.add([]); // no change

twoKeyStore.add({
  i: {
    j: 6,
    k: 7
  }
});
// ['b', 'c']: 2
// ['b', 'd']: 3
// ['e', 'f']: {g: 4, h: 5}
// ['i', 'j']: 6
// ['i', 'k']: 7


twoKeyStore.add({
  a: {
    x: 8
  },
  b: 'a string', // ignored
  e: undefined,   // ignored,
  i: {
    y: 9
  },
  i: {
    undefined: 6  // ignored    
  },
  null: 7,       // ignored
  NaN: 8         // ignored
});
// ['a', 'x']: 8
// ['b', 'c']: 2
// ['b', 'd']: 3
// ['e', 'f']: {g: 4, h: 5}
// ['i', 'j']: 6
// ['i', 'k']: 7
// ['i', 'y']: 9

has(k1, [k2])

If k1 and k2 are supplied, returns true if there is an entity stored against this nested key.

If only k1 is supplied, returns true if there are any entities stored under this top-level key.

If k1 is undefined this will always return false. An error will be thrown if k1 is otherwise invalid.

const twoKeyStore = new TwoKeyStore({
  a: {
    b: 1,
    c: 2
  },
  d: {
    e: 3,
    f: 4
  }
});

twoKeyStore.has('a');             // true
twoKeyStore.has('b');             // false
twoKeyStore.has('x');             // false
twoKeyStore.has('a', 'b');        // true
twoKeyStore.has('a', 'd');        // false
twoKeyStore.has('a', 'e');        // false
twoKeyStore.has('a', 'x');        // false
twoKeyStore.has(undefined, 'x');  // false
twoKeyStore.has('a', undefined);  // true

get(k1, [k2])

If k1 and k2 are supplied, returns the entity stored under nested key [k1, k2], or undefined if there is nothing stored against this nested key.

If only k1 is supplied, returns the nested object under that top-level key, or undefined if there is nothing stored under this top-level key.

If k1 is undefined this will always return undefined. An error will be thrown if k1 is otherwise invalid.

const twoKeyStore = new TwoKeyStore({
  a: {
    b: 1,
    c: undefined
  },
  d: {
    e: 2,
    f: 3
  }
});

twoKeyStore.get('a');            // {b: 1, c: undefined}
twoKeyStore.get('a', 'b');       // 1
twoKeyStore.get('a', 'b');       // 1
twoKeyStore.get('a', 'c');       // undefined
twoKeyStore.get('a', 'y');       // undefined
twoKeyStore.get('x', 'y');       // undefined
twoKeyStore.get(undefined, 'y'); // undefined
twoKeyStore.get('a', undefined); // {b: 1, c: undefined}

keys([k1])

If k1 is supplied, returns the keys of the nested object stored under this top-level key, or an empty array if nothing is stored under this top-level key.

If no argument are supplied, returns the top-level keys, or an empty array if the store is empty.

An error will be thrown if k1 is defined and invalid.

const twoKeyStore = new TwoKeyStore({
  a: {
    b: 1,
    c: 2
  },
  d: {
    e: 3,
    f: 4
  }
});
const topLevelKeys = twoKeyStore.keys();      // ['a', 'd']
const keysForA = twoKeyStore.keys('a');       // ['b', 'c']
const keysForUnknown = twoKeyStore.keys('x'); // []
(new TwoKeyStore()).keys();                   // []

values([k1])

If k1 is supplied, returns all the values stored under this top-level key, or an empty array if nothing is stored under this top-level key.

If no arguments are supplied, returns all the values in the store, or an empty array if the store is empty.

If k1 is invalid it will be treated as undefined.

const twoKeyStore = new TwoKeyStore({
  a: {
    b: 1,
    c: 2
  },
  d: {
    e: 3,
    f: 1
  }
});

twoKeyStore.values();         // [1, 2, 3, 1]
twoKeyStore.values('a');      // [1, 2]
twoKeyStore.values('c');      // []
(new TwoKeyStore()).values(); // []

entries([k1])

If k1 is supplied, returns all entries stored under this top-level key as triples, or an empty list if nothing is stored under this top-level key.

If no arguments are supplied, returns all the entries in the store as a triple, or an empty array if the store is empty.

An error will be thrown if k1 is defined and invalid.

const twoKeyStore = new TwoKeyStore({
  a: {
    b: 1,
    c: 2
  },
  d: {
    e: 3,
    f: 4
  }
});

twoKeyStore.entries();
// [
//   ['a', 'b', 1],
//   ['a' ,'c', 2],  
//   ['d' ,'e', 3],  
//   ['d' ,'f', 4],  
// ]

twoKeyStore.entries('a');
// [
//   ['a', 'b', 1],
//   ['a' ,'c', 2],  
// ]

twoKeyStore.entries('x');       // []
(new TwoKeyStore()).entries();  // []

forEach(fn)

Applies the fn to each entity in the store, with the keys passed as secondary arguments.

const twoKeyStore = new TwoKeyStore({
  a: {
    b: 1,
    c: 2
  },
  d: {
    e: 3,
    f: 4
  }
});

twoKeyStore.forEach((entity, k1, k2) => console.log(entity, k1, k2));
// 1 a b
// 2 a c
// 3 d e
// 4 d f 

delete(k1, [k2])

If k1 and k2 are supplied, this will delete the entity stored against this nested key, if one exists.

If only k1 is supplied, this will delete all entities with k1 as the top-level key, if there are any.

An error will be thrown if k1 is invalid or if k2 is defined and invalid.

const twoKeyStore = new TwoKeyStore({
  a: {
    b: 1,
    c: 2
  },
  d: {
    e: 3,
    f: 4
  }
});
// ['a', 'b']: 1
// ['a', 'c']: 2
// ['d', 'e']: 3
// ['d', 'f']: 4


twoKeyStore.delete('a', 'b');
// ['a', 'c']: 2
// ['d', 'e']: 3
// ['d', 'f']: 4

twoKeyStore.delete('d');
// ['a', 'c']: 2

clear()

Clears all entities from the store.

const twoKeyStore = new TwoKeyStore({
  a: {
    b: 1,
    c: 2
  },
  d: {
    e: 3,
    f: 4
  }
});
// ['a', 'b']: 1
// ['a', 'c']: 2
// ['d', 'e']: 3
// ['d', 'f']: 4


twoKeyStore.clear();
// empty

isEmpty()

Returns true if there are no entities in the store.

const twoKeyStore = new TwoKeyStore();

twoKeyStore.isEmpty(); // true

twoKeyStore.add({
  a: {
    b: 1,
    c: 2
  },
  d: {
    e: 3,
    f: 4
  }
});
twoKeyStore.isEmpty(); // false

twoKeyStore.clear();
twoKeyStore.isEmpty(); // true

twoKeyStore.set('a', 'b', 1);
twoKeyStore.isEmpty(); // false

twoKeyStore.delete('a');
twoKeyStore.isEmpty(); // true

toObject()

Returns the store as an object literal.

const twoKeyStore = new TwoKeyStore();

twoKeyStore.toObject(); // {}


twoKeyStore.add({
  a: {
    b: 1,
    c: 2
  },
  d: {
    e: 3,
    f: 4
  }
});
twoKeyStore.toObject(); // {a: {b: 1, c: 2}, d: {e: 3, f: 4}}

License

UNLICENSED © Alastair Brayne