postal.diagnostics
Version:
Wiretap add-on for postal.js allowing configurable console.logging (or other) output of messages being published through postal's message bus.
136 lines • 4.63 kB
JavaScript
/**
* conduitjs - Give any method a pre/post invocation pipeline....
* Author: Jim Cowart (http://freshbrewedcode.com/jimcowart)
* Version: v0.3.3
* Url: http://github.com/ifandelse/ConduitJS
* License: MIT
*/
(function (root, factory) {
if (typeof module === "object" && module.exports) {
// Node, or CommonJS-Like environments
module.exports = factory();
} else if (typeof define === "function" && define.amd) {
// AMD. Register as an anonymous module.
define([], factory(root));
} else {
// Browser globals
root.Conduit = factory(root);
}
}(this, function (global, undefined) {
function Conduit(options) {
if (typeof options.target !== "function") {
throw new Error("You can only make functions into Conduits.");
}
var _steps = {
pre: options.pre || [],
post: options.post || [],
all: []
};
var _defaultContext = options.context;
var _target = options.target;
var _targetStep = {
isTarget: true,
fn: options.sync ?
function () {
var args = Array.prototype.slice.call(arguments, 0);
var result = _target.apply(_defaultContext, args);
return result;
} : function (next) {
var args = Array.prototype.slice.call(arguments, 1);
args.splice(1, 1, _target.apply(_defaultContext, args));
next.apply(this, args);
}
};
var _genPipeline = function () {
_steps.all = _steps.pre.concat([_targetStep].concat(_steps.post));
};
_genPipeline();
var conduit = function () {
var idx = 0;
var retval;
var phase;
var next = function next() {
var args = Array.prototype.slice.call(arguments, 0);
var thisIdx = idx;
var step;
var nextArgs;
idx += 1;
if (thisIdx < _steps.all.length) {
step = _steps.all[thisIdx];
phase = (phase === "target") ? "after" : (step.isTarget) ? "target" : "before";
if (options.sync) {
if (phase === "before") {
nextArgs = step.fn.apply(step.context || _defaultContext, args);
next.apply(this, nextArgs || args);
} else {
retval = step.fn.apply(step.context || _defaultContext, args) || retval;
next.apply(this, [retval].concat(args));
}
} else {
step.fn.apply(step.context || _defaultContext, [next].concat(args));
}
}
};
next.apply(this, arguments);
return retval;
};
conduit.steps = function () {
return _steps.all;
};
conduit.context = function (ctx) {
if (arguments.length === 0) {
return _defaultContext;
} else {
_defaultContext = ctx;
}
};
conduit.before = function (step, options) {
step = typeof step === "function" ? {
fn: step
} : step;
options = options || {};
if (options.prepend) {
_steps.pre.unshift(step);
} else {
_steps.pre.push(step);
}
_genPipeline();
};
conduit.after = function (step, options) {
step = typeof step === "function" ? {
fn: step
} : step;
options = options || {};
if (options.prepend) {
_steps.post.unshift(step);
} else {
_steps.post.push(step);
}
_genPipeline();
};
conduit.clear = function () {
_steps = {
pre: [],
post: [],
all: []
};
_genPipeline();
};
conduit.target = function (fn) {
if (fn) {
_target = fn;
}
return _target;
};
return conduit;
};
return {
Sync: function (options) {
options.sync = true;
return Conduit.call(this, options)
},
Async: function (options) {
return Conduit.call(this, options);
}
}
}));