stash-it
- createCache(adapter)
- registerPlugins(cacheInstance, plugins)
- createItem(key, value, namespace, [extra])
- getPreData(methodName, args)
- getPostData(methodName, args)
createCache(adapter)
This method creates cache instance.
Arguments
adapter
(Adapter): Adapter's instance, any combiatible with stash-it. See list of available adapters.
Throws
- If
adapter
is not an object, it will throw an error'adapter' must be an object.
- If
adapter
does not contain all required methods, it will throw an errorNot all required methods are present in adapter.
- If not all of the methods are functions, it will throw an error
Not all required methods are functions.
Returns
(cacheInstance): Created cache instance.
Example
import { createCache } from 'stash-it';
import createAdapter from 'any-stash-it-compatible-adapter'; // e.g. stash-it-adapter-memory
const adapter = createAdapter({ namespace: 'someNamespace' });
const cacheInstance = createCache(adapter);
registerPlugins(cacheInstance, plugins)
Registers plugins on cacheInstance.
Arguments
cacheInstance
(cacheInstance): Cache instance created using createCache method.plugins
(array): Array of plugins (one or many)
Throws
- If
cacheInstance
is not an object, it will throw an error'cacheInstance' must be an object.
- If
plugins
are not passed as an array, it will throw an error'plugins' must be passed as an array.
- If any of the plugins won't contain
hook
orgetExtension
method (at least one of them), it will throw an errorPlugin must contain hooks or getExtensions method or both.
Returns
(cacheInstance): Cache instance with extended functionality.
Examples
import { createCache, registerPlugins } from 'stash-it';
import createAdapter from 'any-stash-it-compatible-adapter'; // e.g. stash-it-adapter-memory
import createPlugin from 'any-stash-it-compatible-plugin'; // e.g. stash-it-plugin-debug
import createOtherPlugin from 'other-stash-it-compatible-plugin';
const adapter = createAdapter({ namespace: 'someNamespace' });
const cache = createCache(adapter);
const plugin = createPlugin();
const extendedCache1 = registerPlugins(cache, [ plugin ]);
// You can further register more plugins
const otherPlugin = createOtherPlugin();
const extendedCache2 = registerPlugins(extendedCache1, [ otherPlugin ]);
// Now, all cache instances will behave differently
// (assuming that plugins added / changed some of the functionality)
// but they will still use the same storage (via adapter).
How can I use different cache instances, ones that have different plugins registered, but having the same adapter underneath?
Let's imagine, that you have a read-only plugin that changes the behavior of setItem
and removeItem
in such way, that user can't set new items (also change existing ones) nor delete them.
// assuming that imports are there
const cache = createCache(createAdapter({ namespace: 'someNamespace' });
const readOnlyPlugin = createReadOnlyPlugin();
const readOnlyCache = registerPlugins(cache, [ readOnlyPlugin ]);
// setting an item in one place
cache.setItem('key', 'value');
// reading an item in other place
readOnlyCache.hasItem('key'); // true
readOnlyCache.getItem('key'); // returns an Item
// trying to set an item, any
readOnlyCache.setItem('key', 'value2'); // false or throw or however this plugin would behave
// trying to remove this item
readOnlyCache.removeItem('key'); // false or throw or however this plugin would behave
// whereas original cache instance
cache.removeItem('key'); // true
(see: Item)
By combining different plugins you can create any behavior of cache's instance. It all depends on the combination of plugins you use.
There is one thing you have to remember:
Order of registering plugins matter. If you register plugins 1, 2 and 3, and they alter somehow given method, data will flow first through plugin 1, then 2 and finally 3 while using that method.
Be sure to check out plugins and lifecycle of methods for more detailed information.
createItem(key, value, namespace, [extra])
Creates an item.
Arguments
key
(string): key, under which given item will be stored. See buildKey (Adapter API)value
(any): value that is to be stored. See values.namespace
(string): namespace. See namespaces.extra
(object): extra data, optional. Will default to empty object if not passed{}
. See Item for more info.
Throws
- If
extra
is not passed as an object, it will throw an error'extra' must be an object.
Returns
(Item): Created item.
Example
import { createItem } from 'stash-it';
const item = createItem('key', 'value', 'namespace');
// OR
const itemWithPassedExtra = createItem('key', 'value', 'namespace', { some: 'additional stuff' });
Why namespace is required as an argument?
Before answering this, you need to know something important: createItem
is best used in adapters. Why there? It's about all adapters having the same way of storing an item in any storage they use. Why? So that once extracted they have the very same structure.
Now, namespace
. As you already know, namespace is required by design by all adapters, so you always have it at that point. In order to store an information what namespace an item belongs to, namespace is explicitly stored in an item as a separate property. And for that this argument is required for this method. And yes, when creating a key, namespace can be used as well, but that is not required by design, thus the need of having separate property.
getPreData(methodName, args)
This method returns pre
(in terms of lifecycle of given method) data which is passed through all of the hooks registered for that particular method.
Arguments
methodName
(string): method name, any one of which API adapter provides (e.g.getItem
) or one provided by plugin(s).args
(object): object with arguments that will be passed through all of the hooks registered formethodName
for it'spre
lifecycle part.
Throws
- If
methodName
is not passed as a string, it will throw an error'methodName' must be a string.
- If
args
is not passed as an object, it will throw an error'args' must be an object.
- If
args
donesn't containcacheInstance
property (which is a reference to cacheInstance), it will throw an error'args' must contain 'cacheInstance' property.
Returns
(object): An object, that was passed through all (if any) registered hooks for given methodName
. Returned object will (should, see requirements) contain the very same properties as ones passed in args
object. Values might change. cacheInstance
should be exactly the same reference to cacheInstance (but it eventually depends on the plugins registered).
Example
import { getPreData } from 'stash-it';
// this will be used mostly, if not only, in plugins hooks
// key and cacheInstance are passed hereby convention
// different arguments will be passed for different methods getPreData is going to be run against
const preData = getPreData('getItem', { key, cacheInstance });
// preData will contain both 'key' and 'cacheInstance' properties
(see: writing plugins)
getPostData(methodName, args)
This method returns post
(in terms of lifecycle of given method) data which is passed through all of the hooks registered for that particular method.
Arguments
methodName
(string): method name, any one of the API adapter provides (e.g.getItem
) or one provided by plugin(s).args
(object): object with arguments that will be passed through all of the hooks registered formethodName
for it'spost
lifecycle part.
Throws
- If
methodName
is not passed as a string, it will throw an error'methodName' must be a string.
- If
args
is not passed as an object, it will throw an error'args' must be an object.
- If
args
doesn't containcacheInstance
property (which is a reference to cacheInstance), it will throw an error'args' must contain 'cacheInstance' property.
Returns
(object): An object, that was passed through all (if any) registered hooks for given methodName
. Returned object will (should, see requirements) contain the very same properties as ones passed in args
object. Values might change. cacheInstance
should be exactly the same reference to cacheInstance (but it eventually depends on the plugins registered).
Example
import { getPostData } from 'stash-it';
// this will be used mostly, if not only, in plugins hooks
// key, item and cacheInstance are passed hereby convention
// different arguments will be passed for different methods getPostData is going to be run against
const postData = getPostData('getItem', { key, item, cacheInstance });
// postData will contain 'key', 'item' and 'cacheInstance' properties
(see: writing plugins)