p-kvstore
This is a basic promise based Key/Value store, that has the builtin ability to:
- detect write-conflicts / prevent data-clobbering
- provides basic needs to allow for value-based caching.
- can be directed to a local backend as well as to a remote one
- can be easily inherited to implement a new storage backend
- can be easily wrapped to add functionality
The main purpose for this is to serve as an abstract to base other implementations of.
However a basic in Map
-based implementation is there.
This package also provides a test-rig that can run compliance tests on any instance given it using tap.
Consumer API
const MapStore = MapStore;const store = ;store;store;store;store;store;
Methods
has(key)
=> Promise.resolve(<boolean>)
get(key)
=> Promise.resolve(<stream.Readable>)
get(key, <ctag|null>)
=> Promise.resolve({ ctag, content:<stream.Readable> })
set(key, value[, ctag])
=> Promise.resolve(ctag)
force(key, value)
=> Promise.resolve(ctag)
delete(key)
=> Promise.resolve(undefined)
Implementor API
const AbstractStore = Abstract;const MyImplementation = ;
is equivalent to:
const AbstractStore = Abstract; {...}MyImplementationprototye = Object;MyImplementationprototye {...};MyImplementationprototye {...};MyImplementationprototye {...};MyImplementationprototye {...};
Methods
The methods can rely on their arguments in the following regard.
- any
id
will be aString
suitable as a file/directory name - any
value
will be astream.Readable
- any
ctag
will be either aString
or undefined
A ctag
is defined as a string that uniquely identifies a value
where identical
value
s will also have identical ctag
s. (think of a sha256 hash for example)
The methods are required to return:
- An array or
Promise
that resolves to an array of no more than 2 elements. - All item of a result must be defined and valid
- The first member of the result (if present) is the valid ctag of the relevant content
- The second member of the result (if present) is a
stream.Readable
has(id)
=> [ ctag ]
If an element is present its ctag
is returned. Otherwise the return is an empty array.
get(id)
=> [ ctag, value ]
If an element is present its ctag
and a stream.Readable
of its content is returned.
Otherwise the result is a rejection with reason.code
set to Abstract.NOT_FOUND
set(id, value, ctag)
=> [ ctag ]
If ctag
is Abstract.CREATE
and the value exists the operation must result in
a rejection with reason.code
set to Abstract.CONFLICT
.
If ctag
is Abstract.FORCE
any value present must be overwritten.
Otherwise if ctag
does not match the current ctag
(if existing) the operation
must result in a rejection with reason.code
set to Abstract.CONFLICT
.
Only of these check pass must the value
be stored.
The result must be the ctag
of the new value
.
delete(id)
=> []
delete
should always succeed regardless of whether a value exists or not.