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

multimix

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

multimix - npm Package Compare versions

Comparing version 0.0.6 to 1.0.0

artwork/JavaScriptObjects--Full.png

220

lib/main.js

@@ -1,6 +0,8 @@

// Generated by CoffeeScript 1.10.0
// Generated by CoffeeScript 2.3.2
(function() {
var CND, MULTIMIX, alert, badge, debug, echo, help, info, join, log, rpr, urge, warn, whisper, σ_finalize, σ_new_state, σ_reject, σ_unknown_type,
slice = [].slice;
'use strict';
var CND, Multimix, alert, badge, debug, help, info, module_keywords, rpr, urge, warn, whisper,
indexOf = [].indexOf;
//###########################################################################################################
CND = require('cnd');

@@ -10,14 +12,10 @@

badge = 'MULTIMIX';
badge = 'MULTIMIX/main';
log = CND.get_logger('plain', badge);
debug = CND.get_logger('debug', badge);
info = CND.get_logger('info', badge);
alert = CND.get_logger('alert', badge);
whisper = CND.get_logger('whisper', badge);
alert = CND.get_logger('alert', badge);
debug = CND.get_logger('debug', badge);
warn = CND.get_logger('warn', badge);

@@ -29,134 +27,106 @@

echo = CND.echo.bind(CND);
info = CND.get_logger('info', badge);
join = require('path').join;
//===========================================================================================================
// MODULE METACLASS provides static methods `@extend()`, `@include()`
//-----------------------------------------------------------------------------------------------------------
/* The little dance around the module_keywords variable is to ensure we have callback support when mixins
extend a class. See https://arcturo.github.io/library/coffeescript/03_classes.html */
//-----------------------------------------------------------------------------------------------------------
module_keywords = ['extended', 'included'];
σ_new_state = Symbol["for"]('new_state');
σ_reject = Symbol["for"]('reject');
σ_finalize = Symbol["for"]('finalize');
σ_unknown_type = Symbol["for"]('unknown_type');
MULTIMIX = {};
MULTIMIX.TOOLS = require('./tools');
MULTIMIX.RECIPES = require('./recipes');
MULTIMIX.COPIERS = require('./copiers');
MULTIMIX._get_seed = function(S, seed) {
var copy, description, has_fields, type;
type = CND.type_of(seed);
description = MULTIMIX.COPIERS.type_descriptions[type];
if (description == null) {
description = MULTIMIX.COPIERS.type_descriptions[σ_unknown_type];
}
has_fields = description.has_fields, copy = description.copy;
return copy.call(MULTIMIX, S, seed);
};
MULTIMIX.mix = function(mixins, recipe, root, selector) {
var S, field_key, field_value, fields, hook, i, len, mixin, mixin_seed, mixin_tail, mx_key, mx_value, partial_mixins, ref, ref1, ref2, seed, type;
if (root == null) {
root = null;
}
if (selector == null) {
selector = [];
}
if (mixins.length === 0) {
return null;
}
mixin_seed = mixins[0], mixin_tail = 2 <= mixins.length ? slice.call(mixins, 1) : [];
S = MULTIMIX.RECIPES[σ_new_state](recipe, mixins);
seed = MULTIMIX._get_seed(S, mixin_seed);
S.seed = seed;
if (root == null) {
root = seed;
}
/* TAINT this part needs to be rewritten */
/* Deal with nested recipe first: */
if ((fields = S.recipe['fields']) != null) {
for (field_key in fields) {
field_value = fields[field_key];
if (!CND.isa_pod(field_value)) {
continue;
}
selector.push(field_key);
partial_mixins = (function() {
var i, len, results;
results = [];
for (i = 0, len = mixins.length; i < len; i++) {
mixin = mixins[i];
if (mixin[field_key]) {
results.push(mixin[field_key]);
}
Multimix = (function() {
//===========================================================================================================
class Multimix {
//---------------------------------------------------------------------------------------------------------
static extend(object) {
var key, ref, value;
for (key in object) {
value = object[key];
if (indexOf.call(module_keywords, key) < 0) {
this[key] = value;
}
return results;
})();
if (partial_mixins.length > 0) {
S.seed[field_key] = MULTIMIX.mix(partial_mixins, field_value, root, selector);
}
S.recipe[field_key] = 'skip';
selector.pop(field_key);
if ((ref = object.extended) != null) {
ref.apply(this);
}
return this;
}
}
/* Process unnested recipe: */
for (i = 0, len = mixins.length; i < len; i++) {
mixin = mixins[i];
for (mx_key in mixin) {
mx_value = mixin[mx_key];
S.path = join.apply(null, slice.call(selector).concat([mx_key]));
S.root = root;
S.current = S.seed;
S.recipe_name = (ref = (ref1 = S.recipe['fields']) != null ? ref1[mx_key] : void 0) != null ? ref : S.recipe_fallback;
if (CND.isa_pod(S.recipe_name)) {
continue;
//---------------------------------------------------------------------------------------------------------
static include(object) {
var key, ref, value;
for (key in object) {
value = object[key];
if (indexOf.call(module_keywords, key) < 0) {
// Assign properties to the prototype
this.prototype[key] = value;
}
}
if (MULTIMIX.RECIPES[σ_reject](S, mx_key, mx_value)) {
continue;
if ((ref = object.included) != null) {
ref.apply(this);
}
if ((recipe = MULTIMIX.RECIPES[S.recipe_name]) == null) {
throw new Error("unknown recipe " + (rpr(S.recipe_name)));
return this;
}
//---------------------------------------------------------------------------------------------------------
export_methods() {
/* Return an object with methods, bound to the current instance. */
var R, k, ref, ref1, v;
R = {};
ref = this;
for (k in ref) {
v = ref[k];
if ((v != null ? v.bind : void 0) == null) {
continue;
}
if ((ref1 = v[Multimix.isa_keymethod_proxy]) != null ? ref1 : false) {
R[k] = Multimix.get_keymethod_proxy(this, v);
} else {
R[k] = v.bind(this);
}
}
recipe.call(MULTIMIX.RECIPES, S, mx_key, mx_value);
return R;
}
}
MULTIMIX.RECIPES[σ_finalize](S);
if ((hook = (ref2 = S.recipe) != null ? ref2['after'] : void 0) != null) {
if ((type = CND.type_of(hook)) !== 'function') {
throw new Error("expected function for 'after' hook, got a " + type);
//=========================================================================================================
// KEYMETHOD FACTORY
//---------------------------------------------------------------------------------------------------------
static get_keymethod_proxy(bind_target, f) {
var R;
R = new Proxy(f.bind(bind_target), {
get: function(target, key) {
if (key === 'bind') { // ... other properties ...
return target[key];
}
if ((Multimix.js_type_of(key)) === 'symbol') {
return target[key];
}
return function(...xP) {
return target(key, ...xP);
};
}
});
R[Multimix.isa_keymethod_proxy] = true;
return R;
}
hook(S);
}
return S.seed;
};
MULTIMIX.use = function() {
var R, recipe, recipes;
recipes = 1 <= arguments.length ? slice.call(arguments, 0) : [];
recipes.splice(0, 0, {
'fallback': 'assign'
});
recipe = MULTIMIX.mix(recipes);
R = function() {
var mixins;
mixins = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return MULTIMIX.mix(mixins, recipe);
//=========================================================================================================
static js_type_of(x) {
return ((Object.prototype.toString.call(x)).slice(8, -1)).toLowerCase();
}
};
R.use = MULTIMIX.use;
return R;
};
module.exports = {
mix: MULTIMIX.use()
};
Multimix.isa_keymethod_proxy = Symbol('proxy');
return Multimix;
}).call(this);
//###########################################################################################################
module.exports = Multimix;
}).call(this);
//# sourceMappingURL=main.js.map
{
"name": "multimix",
"version": "0.0.6",
"version": "1.0.0",
"description": "flexible object copying",

@@ -30,7 +30,7 @@ "main": "lib/main.js",

"devDependencies": {
"guy-test": "^1.2.3"
"guy-test": "^1.4.0"
},
"dependencies": {
"cnd": "^4.1.5"
"cnd": "^4.5.0"
}
}

@@ -1,33 +0,129 @@

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [MultiMix](#multimix)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
![](https://raw.githubusercontent.com/loveencounterflow/multimix/master/artwork/multimix.png)
<!--
# MultiMix
Conventional inheritance in its two main
An ES6 `class` with some metaprogramming capabilities:
—the 'classical' variant known from languages like Java, Python and others as well
as the 'prototypal' variant known mainly from JavaScript—both assert
* easy to mixin instance methods from an arbitrary number of objects;
* easy to mixin static (class) methods from an arbitrary number of objects;
* sample implementation for a kind of 'keymethod proxies' (essentially instance method with custum special
behavior);
* ability to 'export' an object with methods bound to a particular instance (great in conjunction with ES6
object destructuring).
* that it makes sense to 'derive' one object (the 'derivative') from another (its 'antetype')
Implementation was inspired by / copy-pasted from [Chapter 3 of *The Little Book on
CoffeeScript*](https://arcturo.github.io/library/coffeescript/03_classes.html).
* both to conserve memory and to organize functionalities;
## Usage
* that the only formally supported *intentional* relationship between a derivative and its antetype should
be 'is-a' (to the exclusion of 'has-a', 'uses-a', 'partly-resembles-a' &c);
Have a look at [the
demo](https://github.com/loveencounterflow/multimix/blob/master/src/experiments/demo.coffee):
* that the only formally defined *extensional* relationship between the attributes of a derived object and
those of its antetype should be take-all-or-override-all: either your derivation has an attribute `x` or
it doesn't; if it does, it will simply override (shadow) any attribute by the same name in the antetype.
* `class X extends Multimix` gives you a class with the following static methods inherited through
`Multimix`:
Crucially, the only way to *formally* derive one object from another is to provide a list of overriding
features, period.
* `<class>.extend: ( object ) ->`—extends class with the properties of `object` (class-level mixin).
* `<class>.include: ( object ) ->`—extends instances with the properties of `object` (instance-level
mixin).
* `<class>.get_keymethod_proxy = ( bind_target, f ) ->`—produces an instance method `f` which will
translate calls from immediate attributes (as in, `f.some_text some_value`) to calls to `f` proper,
using the attribute name as first argument: `f some_text, some_value`. I needed this for a specific
purpose and included the code as a demo how to implement such a thing.
* `export_methods: ->`—when called on an instance, returns an object with bound instance methods; this
allows to 'export' instance methods into a namespace without fearing 'JavaScript method tear-off
symptome':
```coffee
my_instance = new My_class
{ method_a
method_b } = my_instance.export_methods()
# now you can use `method_a`, `method_b` without prefixing them with `my_instance`:
method_a 42
```
Code:
-->
```coffee
Multimix = require 'multimix'
#=========================================================================================================
# SAMPLE OBJECTS WITH INSTANCE METHODS, STATIC METHODS
#---------------------------------------------------------------------------------------------------------
object_with_class_properties =
find: ( id ) -> info "class method 'find()'", ( k for k of @ )
create: ( attrs ) -> info "class method 'create()'", ( k for k of @ )
#---------------------------------------------------------------------------------------------------------
object_with_instance_properties =
save: -> info "instance method 'save()'", ( k for k of @ )
#=========================================================================================================
# CLASS DECLARATION
#---------------------------------------------------------------------------------------------------------
isa = ( type, xP... ) ->
### NOTE realistic method should throw error when `type` not in `specs` ###
urge "µ1129 object #{rpr @instance_name} isa #{rpr type} called with #{rpr xP}"
urge "µ1129 my @specs: #{rpr @specs}"
urge "µ1129 spec for type #{rpr type}: #{rpr @specs[ type ]}"
#---------------------------------------------------------------------------------------------------------
class Intertype extends Multimix
@extend object_with_class_properties
@include object_with_instance_properties
#-------------------------------------------------------------------------------------------------------
constructor: ( @instance_name ) ->
super()
@specs = {}
@declare type, value for type, value of @constructor.base_types
@isa = Multimix.get_keymethod_proxy @, isa
#-------------------------------------------------------------------------------------------------------
declare: ( type, value ) ->
whisper 'µ7474', 'declare', type, rpr value
@specs[ type ] = value
#-------------------------------------------------------------------------------------------------------
@base_types =
foo: 'spec for type foo'
bar: 'spec for type bar'
##########################################################################################################
intertype_1 = new Intertype
intertype_2 = new Intertype
info 'µ002-1', Intertype.base_types
info 'µ002-2', intertype_1.declare 'new_on_it1', 'a new hope'
info 'µ002-3', 'intertype_1.specs', intertype_1.specs
info 'µ002-4', 'intertype_2.specs', intertype_2.specs
info 'µ002-5', intertype_1.isa 'new_on_it1', 1, 2, 3
info 'µ002-6', intertype_1.isa.new_on_it1 1, 2, 3
info 'µ002-7', intertype_2.isa 'new_on_it1', 1, 2, 3
info 'µ002-8', intertype_2.isa.new_on_it1 1, 2, 3
{ isa, declare, } = intertype_1.export_methods()
info 'µ002-9', isa 'new_on_it1', 1, 2, 3
info 'µ002-10', isa.new_on_it1 1, 2, 3
```
## Links
* [jeremyckahn/inherit-by-proxy.js](https://gist.github.com/jeremyckahn/5552373)
* [JS Objects: Distractions](https://davidwalsh.name/javascript-objects-distractions)
* [JS Objects: De"construct"ion](https://davidwalsh.name/javascript-objects-deconstruction)
## Motivation
"JavaScript's prototypal inheritance is vastly simpler than class-based, 'classical' OOP".&nbsp;<sup>*[citation
needed]*</sup>
[Is it](https://davidwalsh.name/javascript-objects-deconstruction)?
![](https://raw.githubusercontent.com/loveencounterflow/multimix/master/artwork/JavaScriptObjects--Full.png)

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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