diff options
Diffstat (limited to 'lib/output/callHook.js')
-rw-r--r-- | lib/output/callHook.js | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/lib/output/callHook.js b/lib/output/callHook.js new file mode 100644 index 0000000..4914e52 --- /dev/null +++ b/lib/output/callHook.js @@ -0,0 +1,60 @@ +var Promise = require('../utils/promise'); +var timing = require('../utils/timing'); +var Api = require('../api'); + +function defaultGetArgument() { + return undefined; +} + +function defaultHandleResult(output, result) { + return output; +} + +/** + Call a "global" hook for an output + + @param {String} name + @param {Function(Output) -> Mixed} getArgument + @param {Function(Output, result) -> Output} handleResult + @param {Output} output + @return {Promise<Output>} +*/ +function callHook(name, getArgument, handleResult, output) { + getArgument = getArgument || defaultGetArgument; + handleResult = handleResult || defaultHandleResult; + + var logger = output.getLogger(); + var plugins = output.getPlugins(); + + logger.debug.ln('calling hook "' + name + '"'); + + // Create the JS context for plugins + var context = Api.encodeGlobal(output); + + return timing.measure( + 'call.hook.' + name, + + // Get the arguments + Promise(getArgument(output)) + + // Call the hooks in serie + .then(function(arg) { + return Promise.reduce(plugins, function(prev, plugin) { + var hook = plugin.getHook(name); + if (!hook) { + return prev; + } + + return hook.call(context, prev); + }, arg); + }) + + // Handle final result + .then(function(result) { + output = Api.decodeGlobal(output, context); + return handleResult(output, result); + }) + ); +} + +module.exports = callHook; |