Writing plugins
As there is nothing better than learning by example, here is a simple plugin. It adds prefix to a key under which we will store our items. Plugin also adds this information to extra and provides method to get prefix used in that plugin.
Plugin example
Usage example
How does all that work
I will now explain what is going on in every part of this plugin.
prefixPlugin(prefix)
As plugins are simple functions, here we name it prefixPlugin
(there is no rule on how to name it), and pass prefix
to it. In our usage example, we passed a string 'somePrefix'
.
This function will return an object that will have both an array of hooks
and createExtensions
method. As you remember, plugins must have at least one of them (either hooks or createExtensions).
hooks
Hooks are an array of objects that contain event
names and handlers
. Let's have a look at first hook:
This hook uses preBuildKey
event name. This means that whenever key will about to be built, whatever you will do in handler, will happen first, before building the key. Here, the key that user will pass, will be prefixed with our prefix. See: preBuildKey. We're returning an object containing key
and cacheInstance
properties, as this is what buildKey
lifecycle for post
part will require.
2nd hook:
This hook uses preSetItem
event name. This means that whenever an item will about to be set, whatever you will do in handler, will happen first, before setting that item. Here, we are taking prefix and adding it to the extra data to store it in the item.
Now that hooks are explained, let's have a look at createExtensions.
createExtensions()
It must return an object with methods. Any methods? Not quite, have a look at registerPlugins API to see when it can throw. So, this is our object, with methods we want our cache to be extended with:
What about lifecycle for each added methods, do I need to add them?
No. Here, in above example you don't need to. But it is a very good practice to add support for lifecycle of those methods.
As above plugin did not needed that, let's have a look, again, at a plugin shown in createExtensions docs. I will (almost) copy and paste whatever is written there for the sake of having this info on one page here. First, the plugin:
This new (not present in stash-it) method is ready for events preGetItems
and postGetItems
. If you would be a creator of such a plugin, your responsibility is to provide detailed information how lifecycle of such a method looks like:
what event names are here (by convention it's the same as created method's name, plus
pre
andpost
prefixes); here we will havepreGetItems
andpostGetItems
;what properties are passed in 2nd argument to
getPreData
andgetPostData
; here we will have:for
pre
object:{ keys, cacheInstance }
and for
post
:{ keys, items, cacheInstance }
what should be returned by each method (
getPreData
andgetPostData
); here we will have:for
pre
:{ keys, cacheInstance }
(so the same as object passed, convention, see below)and for
post
:{ keys, items, cacheInstance }
(same thing as forpre
)
what is returned by newly created method - here an array of items.
Final word
There is no strict rule for what is needed to be passed from preData to postData. There is just a convention that I encourage you to follow, so that all plugins will work as you would expect them to:
pre
handlers should take an object as an argument, with properties being the arguments passed to extension, plus cacheInstancepre
handlers should always return an object with those properties (and cacheInstance)extensions body (any functionality there is) should use / take data only returned by
pre
(including cacheInstance)post
should take an object as an argument, the very same in structure aspre
but with values taken frompre
and with result of extensions methodpost
should return an object with those propertiesfinally that method should return extensions method value passed to
post
and returned by ityou should always check for existence of
item
orextra
as you might want to check their properties, but since they can beundefined
- it's best to check that first.
Remember that createExtensions will always be passed an object of such structure: { cacheInstance, getPreData, getPostData }
Last updated