Components

by plus5keen

JavaScript

(function (global, _) {
    'use strict';
    var undef = void 0;

    function makeClass(methodMap) {
        var construct = methodMap._construct;
        function Class() {
            if (construct) {
                construct.apply(this, arguments);
            }
        }
        var proto = Class.prototype;
        proto.constructor = Class;
        _.extend(proto, methodMap);
        return Class;
    }
    
    var augment = function (op) {
        return { augmentOp: op };
    };
    
    var only = function (op) { // not yet used
        return { onlyOp: op };
    };
    
    var makeComposedClass = function (options) {
        var composedMethods = _.reduce(options.components, function (memo, component) {
            return _.reduce(component, function (memo, op, name) {
                //var isOnly = !!op.onlyOp; // requires a more robust composition state
                //if (isOnly) {
                //    op = op.onlyOp;
                //    return memo;
                //}
                var isAugment = !!op.augmentOp;
                if (isAugment) { op = op.augmentOp; }
                var baseOp = memo[name];
                if (baseOp) {
                    memo[name] = function () {
                        var args = _.toArray(arguments);
                        var baseResult = baseOp.apply(this, args);
                        if (baseResult !== undef) {
                            args[0] = baseResult;
                        }
                        return op.apply(this, args);
                    };
                } else if (!isAugment) {
                    memo[name] = op;
                }
                return memo;
            }, memo);
        }, _.extend({}, options.methods));
        var Composed = makeClass(composedMethods);
        return Composed;
    };
    
    global.coi = {
        makeComposedClass: makeComposedClass,
        augment: augment
    };
}(this, this._));

(function (global, coi) {
    var log =...