Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mixinable

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mixinable - npm Package Compare versions

Comparing version 1.2.0 to 1.2.1

5

CHANGELOG.md

@@ -5,2 +5,7 @@ # Change Log

<a name="1.2.1"></a>
## [1.2.1](https://github.com/dmbch/mixinable/compare/v1.2.0...v1.2.1) (2017-11-30)
<a name="1.2.0"></a>

@@ -7,0 +12,0 @@ # [1.2.0](https://github.com/dmbch/mixinable/compare/v1.1.1...v1.2.0) (2017-11-27)

157

index.js
'use strict';
module.exports = exports = function define (definition) {
var mixinable = createMixinable(definition);
module.exports = exports = function define (strategies) {
return function mixin () {
var mixins = argsToArray(arguments).map(createMixin);
return function create () {
var args = argsToArray(arguments);
return Object.defineProperties(
new (bindArgs(mixinable, args))(),
{
__implementations__: { value: getImplementations(
mixinable,
mixins.map(function (mixin) {
return new (bindArgs(mixin, args))();
})
)},
__clone__: { value: bindArgs(create, args) }
}
);
};
return createMixinable(
strategies || {},
argsToArray(arguments).map(createMixin)
);
};

@@ -71,41 +58,45 @@ };

exports.async = {
override: function () {
return Promise.resolve(exports.override.apply(null, arguments));
override: function overrideAsync () {
return promisify(exports.override.apply(null, arguments));
},
parallel: function () {
return Promise.resolve(exports.parallel.apply(null, arguments));
parallel: function parallelAsync () {
return promisify(exports.parallel.apply(null, arguments));
},
pipe: function () {
return Promise.resolve(exports.pipe.apply(null, arguments));
pipe: function pipeAsync () {
return promisify(exports.pipe.apply(null, arguments));
},
compose: function () {
return Promise.resolve(exports.compose.apply(null, arguments));
compose: function composeAsync () {
return promisify(exports.compose.apply(null, arguments));
}
};
exports.clone = function clone (instance) {
var args = argsToArray(arguments).slice(1);
if (instance && isFunction(instance.__clone__)) {
return instance.__clone__.apply(null, args);
}
exports.replicate = function replicate (handleArgs) {
return function (instance) {
if (instance) {
return new (bindArgs(instance.constructor, handleArgs(
instance.__arguments__ || [],
argsToArray(arguments).slice(1)
)))();
}
};
};
exports.clone = exports.replicate(Array.prototype.concat.bind([]));
// classy helpers
function createMixinable (definition) {
function createMixinable (strategies, mixins) {
var constructor = getConstructor(strategies);
var prototype = getPrototype(strategies);
function Mixinable () {
getConstructor(definition).apply(this, arguments);
var args = argsToArray(arguments);
if (!(this instanceof Mixinable)) {
return new (bindArgs(Mixinable, args))();
}
enhanceInstance.call(this, prototype, mixins, args);
constructor.apply(this, args);
}
var prototype = getPrototype(definition);
Mixinable.prototype = Object.assign(
Object.create(prototype),
Object.keys(prototype).reduce(function (result, key) {
result[key] = function () {
var args = argsToArray(arguments);
var functions = this.__implementations__[key];
var strategy = prototype[key];
return strategy.apply(this, [functions].concat(args));
};
return result;
}, {}),
enhancePrototype(prototype),
{ constructor: Mixinable }

@@ -116,2 +107,35 @@ );

function enhanceInstance (strategies, mixins, args) {
var mixinstances = mixins.map(function (mixin) {
return new (bindArgs(mixin, args))();
});
Object.defineProperties(this, {
__implementations__: {
value: Object.keys(strategies).reduce(function (result, key) {
result[key] = mixinstances
.filter(function (mixinstance) {
return isFunction(mixinstance[key]);
})
.map(function (mixinstance) {
return mixinstance[key].bind(mixinstance);
});
return result;
}, {})
},
__arguments__: { value: args }
});
}
function enhancePrototype (strategies) {
return Object.keys(strategies).reduce(function (result, key) {
result[key] = function () {
var args = argsToArray(arguments);
var functions = this.__implementations__[key];
var strategy = strategies[key];
return strategy.apply(this, [functions].concat(args));
};
return result;
}, {});
}
function createMixin (definition) {

@@ -131,15 +155,19 @@ if (isFunction(definition)) {

function getImplementations (mixinable, mixinstances) {
return Object.keys(mixinable.prototype).reduce(function (result, key) {
result[key] = mixinstances
.filter(function (mixinstance) {
return isFunction(mixinstance[key]);
})
.map(function (mixinstance) {
return mixinstance[key].bind(mixinstance);
});
return result;
}, {});
function getConstructor (obj) {
if (isFunction(obj)) {
return obj;
}
if (obj && obj.hasOwnProperty('constructor')) {
return obj.constructor;
}
return function () {};
}
function getPrototype (obj) {
if (isFunction(obj)) {
return obj.prototype;
}
return obj || Object.create(null);
}
// utilities

@@ -162,19 +190,2 @@

function getConstructor (obj) {
if (isFunction(obj)) {
return obj;
}
if (obj && obj.hasOwnProperty('constructor')) {
return obj.constructor;
}
return function () {};
}
function getPrototype (obj) {
if (isFunction(obj)) {
return obj.prototype;
}
return obj || Object.create(null);
}
function isFunction (obj) {

@@ -187,1 +198,5 @@ return typeof obj === 'function';

}
function promisify (obj) {
return isPromise(obj) ? obj : Promise.resolve(obj);
}
{
"name": "mixinable",
"version": "1.2.0",
"version": "1.2.1",
"description": "Functional JavaScript Mixin Utility",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -38,3 +38,3 @@ # Mixinable

And that `create()` function accepts whatever arguments the `constructor()`s of your mixin container and your mixins accept.
And that `create()` function accepts whatever arguments your `constructor()`s accept.

@@ -101,3 +101,3 @@ ##### Example

Both mixin container and mixin definitions can contain custom constructors. These functions are being passed the `create()` function's arguments upon creation.
Mixin definitions can be (or contain) custom constructors. These functions are being passed the `create()` function's arguments upon creation.

@@ -109,15 +109,17 @@ ##### Example

const mixin = define({
// mixin container contructor
constructor: function (arg) {
console.log(arg);
}
});
const mixin = define();
const create = mixin({
// mixin contructor
constructor: function (arg) {
console.log(arg);
const create = mixin(
// mixin contructors
{
constructor: function (arg) {
console.log(arg);
}
},
class {
constructor (arg) {
console.log(arg);
}
}
});
);

@@ -151,3 +153,3 @@ create('yee-hah!');

},
{
class {
bar () {

@@ -187,3 +189,3 @@ console.log(2);

},
{
class {
bar (val, inc) {

@@ -223,3 +225,3 @@ return val + inc;

},
{
class {
bar (val, inc) {

@@ -226,0 +228,0 @@ return (val + inc);

@@ -10,2 +10,3 @@ 'use strict';

t.equal(typeof mixinable, 'function', 'main export is a function');
t.equal(typeof mixinable.replicate, 'function', 'replicate is a function');
t.equal(typeof mixinable.clone, 'function', 'clone is a function');

@@ -33,20 +34,2 @@ t.equal(typeof mixinable.override, 'function', 'override is a function');

test('clone function test', function (t) {
var arg1 = 1;
var arg2 = 2;
var create = mixinable({
constructor: function (bar, baz) {
this.bar = bar;
this.baz = baz;
}
})();
var instance = create(arg1);
t.equal(instance.bar, arg1, 'instance has expected 1st property');
t.equal(instance.baz, undefined, 'instance does not have 2nd property');
var clone = mixinable.clone(instance, arg2);
t.equal(clone.bar, arg1, 'clone has expected 1st property');
t.equal(clone.baz, arg2, 'clone has expected 2nd property');
t.end();
});
test('constructor support test', function (t) {

@@ -487,1 +470,41 @@ t.plan(4);

});
test('replicate function test', function (t) {
t.plan(3);
var arg1 = 1;
var arg2 = 2;
var create = mixinable({
foo: mixinable.override
})({
constructor: function (bar) {
this.foo = function () { return bar; };
}
});
var instance = create(arg1);
t.equal(instance.foo(), arg1, 'instance returns expected value');
var replicate = mixinable.replicate(function (initialArgs, newArgs) {
t.pass('handleArgs is being called');
return [initialArgs[0] + newArgs[0]];
});
var replica = replicate(instance, arg2);
t.equal(replica.foo(), arg1 + arg2, 'clone returns expected value');
});
test('clone function test', function (t) {
var arg1 = 1;
var arg2 = 2;
var create = mixinable({
foo: mixinable.override
})({
constructor: function (bar, baz) {
this.foo = function () {
return bar + (baz || 0);
};
}
});
var instance = create(arg1);
t.equal(instance.foo(), arg1, 'instance returns expected value');
var clone = mixinable.clone(instance, arg2);
t.equal(clone.foo(), arg1 + arg2, 'clone returns expected value');
t.end();
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc