This proejct is obsolete. It was substituted with the composers introduced in stamp specification v1.5.
This repository will be archived in early 2018.
Hackable implementation of the 'compose' specification
$ npm i make-compose
The following is written using rtype type notation.
interface Stamp (options?: Object|Any, ...args?: Any[]) => Any; {
compose: Compose; Descriptor
}
Initializer(options?: object, ?: { stamp: Stamp, instance: Any, args: Any[] }) => instance: Void|Any
ingerface Descriptor {
methods?: Object,
properties?: Object,
deepProperties?: Object,
propertyDescriptors?: Object,
staticProperties?: Object,
staticDeepProperties?: Object,
staticPropertyDescriptors?: Object,
configuration?: Object,
deepConfiguration?: Object,
initializers?: Initializer[]
}
interface Composable: Stamp|Descriptor
interface Compose (...args?: Composable[]) => Stamp
This function creates and returns the compose
implementation. The options
argument can have the following key-value pairs:
-
mergeComposable: (dstDescriptor: Descriptor, srcComposable: Composable) => dstDescriptor: Descriptor
- merges (mutates) the second argument into the first argument. Returns the first argument. Supply it to track composition. -
createStamp: (descriptor: Descriptor, composeFunction: Compose) => Stamp
- creates new stamp from the given descriptor and thecompose
function. Supply it to track each instantiated stamp. -
createFactory: (descriptor: Descriptor) => Function
- creates a factory function from the given descriptor. Supply it to override factory function creation. -
createObject: (proto: Object) => Object|Any
- given the prototype object creates a new empty object form it. Default value isObject.create
. Supply it to tweak the objects the stamp are gonna return. -
assign: (dst: Object, src: Object) => dst: Object
- supply it to override the defaultObject.assign
implementation. -
merge: (dst: Object, src: Object) => dst: Object
- the stamp-specific merge function. Supply it to override the default implementation.
Use it when you need to track or override each time a composable is merged to the new descriptor object.
import MakeCompose, {mergeComposable} from 'make-compose';
const compose = MakeCompose({
mergeComposable: function (dstDescriptor, srcComposable) {
const name = (srcComposable && ((srcComposable.toString && srcComposable.toString()) || srcComposable.name));
console.log('composing with', name);
return mergeComposable.call(this, dstDescriptor, srcComposable);
}
});
Use it when you need to track or override each new stamp created.
import MakeCompose, {createStamp} from 'make-compose';
let counter = 0;
const compose = MakeCompose({
createStamp: function (descriptor) {
console.log(++counter);
return createStamp(descriptor);
}
});
Use it when your factory function needs to be different to the default one.
import MakeCompose, {createFactory} from 'make-compose';
let counter = 0;
const compose = MakeCompose({
createFactory(descriptor) {
const factory = createFactory.call(this, descriptor);
const name = (counter++).toString();
factory.toString = () => ("Object#" + name);
return factory;
}
});
Use it when you need your stamps to instantiate something different to the regular objects. The default algorithm is simply the Object.create
.
import MakeCompose, {createObject} from 'make-compose';
let counter = 0;
const compose = MakeCompose({
createObject: function (proto) {
console.log(++counter);
return createObject(proto);
}
});
You can also override the Object.assign
implementation. But it is used in many various places. Beware!
import MakeCompose, {assign} from 'make-compose';
let counter = 0;
const compose = MakeCompose({
assign: function (dst, src) {
console.log(++counter);
return assign(dst, src);
}
});
You can also override the stamp-specific deep merge implementation. But it is used in many various places. Beware!
import MakeCompose, {merge} from 'make-compose';
let counter = 0;
const compose = MakeCompose({
merge: function (dst, src) {
console.log(++counter);
return merge(dst, src);
}
});
All the stamps created from this compose
functions are going to:
- have new
toString()
method which returns the stamp dummy name - print the name of the stamp each time it is composed
- count the number of descriptors merged and stamps instantiated
import MakeCompose, {mergeComposable, createStamp, isComposable, isDescriptor}
from 'make-compose';
const counters = {composedDescriptors: 0, createdStamps: 0};
const compose = MakeCompose({
mergeComposable(dstDescriptor, srcComposable) {
if (isComposable(srcComposable)) {
counters.composedDescriptors++;
const name = (srcComposable && ((srcComposable.toString && srcComposable.toString()) || srcComposable.name));
console.log('composing with', name); // Printing the name of the stamp.
}
return mergeComposable.call(this, dstDescriptor, srcComposable);
},
createStamp(descriptor, composeImplementaion) {
counters.createdStamps++;
return createStamp.call(this, descriptor, composeImplementaion);
},
createFactory(descriptor) {
const factory = createFactory.call(this, descriptor);
const name = counters.createdStamps.toString();
factory.toString = () => ("Object#" + name); // Overwriting the default JavaScript "toString"
return factory;
}
});