Lifecycle of methods

Understanding this will help understanding how plugins work and how to write them.

Methods available after creating an instance of cache (see cacheInstance): buildKey, getItem, getExtra, setItem, hasItem and removeItem, have certain lifecycle.

This is how it looks like 'inside':

{
    // (1)
    method(arg) {
        // (2)
        const preData = getPreData('eventName', { arg, cacheInstance: this }); 

        // (3)
        const result = adapter.method(preData.arg);

        // (4)
        const postData = getPostData('eventName', { arg: preData.arg, result, cacheInstance: preData.cacheInstance });

        // (5)
        return postData.result;
    }
}

Here's what is happening:

  1. Given method is called with argument(s) passed to it.
  2. preData is being fetched, which stands for get me data for 'pre' lifecycle part of this method, for event 'eventName' with those arguments.
  3. Adapter's method is being called with arg returned by getPreData .
  4. postData is being fetched, which stands for get me data for 'post' lifecycle part of this method, for event 'eventName' with those arguments.
  5. result that came back from adapter and was passed through getPostData is being returned finally by this method.

Now, let's use getItem method and inspect this in more detail:

// this is an instance of cache
{
    // (1)
    getItem(key) {
        // (2)
        const preData = getPreData('getItem', { cacheInstance: this, key });

        // (3)
        const item = adapter.getItem(this.buildKey(preData.key));

        // (4)
        const postData = getPostData('getItem', { cacheInstance: preData.cacheInstance, key: preData.key, item });

        // (5)
        return postData.item;
    }
}
  1. cache instance's getItem(key) method is called, takes a key as an argument. Depending on method used, there can be more arguments (e.g. setItem(key, value, [extra])).
  2. preData is fetched. There are few things to remember, as there is a pattern here:

    • all methods (ones mentioned at the beginning) have event name passed as a string of value equal to that method's name. So, for example hasItem(key) method will have 'hasItem' string passed, or removeItem(key) will have 'removeItem' passed,

    • getPreData will construct a full event name; here, for pre data, event name will be 'preGetItem' (camelCase); so, for hasItem(key) it will be 'preHasItem' and so on,

    • object being passed alongside event name always contains cacheInstance which is a reference to this which is cache instance itself; this is useful if any plugin will need to use cache's method - be careful with that, as it gives you much power, so be responsible,

    • the same object, for preData will always have the very same properties as arguments passed to called function (alongside cacheInstance), here key; for example hasItem(key) will pass only key and cacheInstance but setItem(key, value, [extra]) will pass key, value, extra and cacheInstance properties (extra defaults to empty object if not passed).

      Checkout all methods in cacheInstance for detailed description what is passed at this point.

    Returned preData (an object) will contain the very same properties, but values of those properties might be different.

    Why?

    If there are hooks added for given event (here 'preGetItem') and handlers (for those events) mutate the data (e.g. add prefix for the key or something else), then that mutated data is returned.
    If there are no hooks added for that event, data is returned without any changes.

    So, here, for getItem method preData will have key and cacheInstance property. There can be additional properties added (by mentioned handlers), but those two will be there always.

  3. Adapter's method is being called, fetching item from storage. There are few things to mention here:

    • for all methods (except for buildKey) key is being built using cache's buildKey method (hence this.buildKey(preData.key),

    • key is being built using key value returned in preData, not key passed to getItem method.

  4. postData is fetched. There are few things to remember, as there is a pattern here as well:

    • all methods (ones mentioned at the beginning) have event name passed as a string of value equal to that method's name. So, for example hasItem(key) method will have 'hasItem' string passed, or removeItem(key) will have 'removeItem' passed,

    • getPostData will construct a full event name; here, for post data, event name will be 'postGetItem' (camelCase); so, for hasItem(key) it will be 'postHasItem' and so on,

    • object being passed alongside event name always contains cacheInstance which is a reference to this which is cache instance itself, but this time it's the one returned in preData; this is useful if any plugin will need to use cache's method - be careful with that, as it gives you much power, so be responsible,

    • the same object, for postData will always have the very same properties as arguments passed to called function (alongside cacheInstance), here key, but also value returned by adapter, and there is a bit difference to what has happened in pre phase: each method (might) pass some additional property. Checkout all methods in cacheInstance for detailed description what is passed at this point.

    Returned postData (an object) will contain the very same properties, but values of those properties might be different.

    Why?

    If there are hooks added for given event (here 'postGetItem') and handlers (for those events) mutate the data (e.g. increment counter how many times item was fetched from cache), then that mutated data is returned.
    If there are no hooks added for that event, data is returned without any changes.

    So, here, for getItem method postData will have key, item and cacheInstance property. There can be additional properties added (by mentioned handlers), but those three will be there always.

  5. Finally, item is returned, one stored in preData, not one returned directly by adapter.

And that's it.

For more details about what is passed and retrieved for all methods and their lifecycle parts, checkout cacheInstance's API docs.


results matching ""

    No results matching ""