Releases: stampit-org/stamp-specification
Getters and Setters built in support
JavaScript getters and setters are now no different to string or Symbol properties. This means that you can have getters in methods, properties, static properties, configuration, etc.
Example:
const HasFullName = compose({
properties: {
firstName: "",
lastName: ""
},
methods: {
get fullName() {
return this.firstName + " " + this.lastName;
},
set fullName(name) {
var words = name.toString().split(" ");
this.firstName = words[0] || "";
this.lastName = words[1] || "";
}
}
});
const developer = HasFullName();
developer.fullName = "Vasyl Boroviak";
console.log(developer.firstName); // "Vasyl"
console.log(developer.lastName); // "Boroviak"
console.log(developer.fullName); // "Vasyl Boroviak"
New feature - composers
More information can be found here.
Composers are designed to mutate the resulting stamp to your needs.
Example:
import stampit from 'stampit';
const SelfAware = stampit()
.composers(({stamp, composables}) => {
const methods = stamp.compose.methods || {};
methods.getStamp = () => stamp; // mutation! Adding a method
stamp.compose.methods = methods;
});
const MyOtherStamp = stampit( ... ).compose(SelfAware); // add the behavior
const obj = MyOtherStamp();
MyOtherStamp === obj.getStamp();
Symbols support
In this release descriptors can have Symbol
s as object keys in addition to the regular string keys.
const S = Symbol();
const Stamp = compose({properties: { [S]: 'foo' }});
Stamp.compose.properties[S] === 'foo';
const instance = Stamp();
instance[S] === 'foo';
Works for deep merged things too.
Standardized merge algorithm
In this release the deep merging algorithm has been standardised. It is:
- Plain objects are deeply merged.
- Array are concatenated.
- Everything else (including Symbols) is copied by assignment.
const ReferencedStamp = compose();
const FirstStamp = compose({deepProperties: {
anotherStamp: null
}});
const SecondStamp = compose({deepProperties: {
anotherStamp: ReferencedStamp
}});
const CombinedStamp = compose(FirstStamp, SecondStamp);
const stampFromMetadata = CombinedStamp.compose.deepProperties.anotherStamp;
Previously the stampFromMetadata
was a POJO:
Object.getPrototypeOf(stampFromMetadata) === Object.prototype
With this release it will be copied by reference:
stampFromMetadata === ReferencedStamp
Default options argument in initializers
In this release the initializers won't need to check if the option argument was passed:
const MyStamp = compose({initializers: [
function (options = {}) { // <-- not needed any more
console.log(options.opt1); // used to throw here
}
]});
The line below will just work now.
const MyStamp = compose({initializers: [
function (options) {
console.log(options.opt1); // used to throw here
}
]});
MyStamp();
Previously it was throwing. So that you always had to pass an empty object:
MyStamp({});
Although, this won't save you from the following:
MyStamp(null); // will throw regardless
MyStamp(42); // will throw regardless
Non duplicate intializers
In this release the descriptor's .initializers
array must not contain duplicate initializers.
function init() {}
const Stamp = compose({ initializers: [init] }).compose({ initializers: [init] });
const stampInitializers = Stamp.compose.initializers;
In previous release the array would contain 2 items:
stampInitializers.length === 2
In this release the array will contain only unique item, i.e. one:
stampInitializers.length === 1