Pluggable
Write your framework or application code in a functional style, and Pluggable will allow consumers of your code to override or transform any part of execution.
Async is fully supported via Promises, and a code analytics tool is made available to compile a dependency graph with metadata for all pluggables you've defined in your code.
pluggable
Define a A pluggable function is defined like so:
const myFunctionName = ;
It's normal function equivalent would look like:
{ // reference functions depA, depB, and depC}
Define a plugin
const myPlugin = { // Any data to persist direct pluggable invocation should be defined here. // Use `override` if you'd like to completely change the implementation of // a pluggable function. ; // Use `transform` if you'd like to modify the output of a pluggable function. ;}
Get a pluggable context and invocation
;const cxt = ;myPluggableFunction;
Full Example
How this works is more easily explained using an example. Imagine you had a module that looked something like this:
; { const signupDate projects contactInfo = userData; return `User "" signed up on and has projects.`;} { return Promiseall github github github ;} { return Promiseallusernames;} // Which would be used like so.;
This is a simple pattern of inputs and outputs - it is easy to test, and easy to reason about.
However, what if you'd like to allow consumers of this module to modify the behavior of one of the functions. What if they want to add additional information, or what if they want to override the behavior altogether? That's where pluggable
comes in.
First, let's rewrite the above example using pluggables - then we'll look at how to modify behavior.
;; const buildSummaryString = ; const getUserData = ; const getUserSummaries = ;
You'll want to especially take note of the changes in getUserSummaries
. Instead of referring to getUserData
and buildSummaryString
directly, it refers to this.getUserData
and this.buildSummaryString
. Under the hood, pluggable
creates this
contexts that make pluggable dependencies available.
Now lets look at how this might be invoked:
;const cxt = ;getUserSummaries;
There's not much extra here beyond the original implementation, aside from providing a context for the function invocation.
Now let's look at how you might implement a caching plugin.
const cacheUserData = { const cache = {}; ; // NOTE: we're not actually transforming the output here, although we could. ;}
You'd invoke getUserSummaries
like so:
;const cxt = ;getUserSummaries;