Composers are callback functions executed each time a composition happens. There can be as many as you wish composers on each stamp.
Composers are a very powerful feature. If you can implement something without composers then it's a good idea to avoid them.
It is highly recommended to not create new stamps in the composers, but mutate the given stamp if necessary.
const InstanceOf = stampit.composers(({ stamp, composables }) => {
if (!stamp.compose.methods) stamp.compose.methods = {} // mutating stamp
stamp.compose.methods.getStamp = () => stamp // mutating stamp
Object.defineProperty(stamp, Symbol.hasInstance, { // mutating stamp
value(obj) {
return obj && typeof obj.getStamp === 'function' && obj.getStamp() === stamp
}
})
})
console.log(InstanceOf() instanceof InstanceOf) // true
console.log(InstanceOf().getStamp() === InstanceOf) // true
const Stamp = InstanceOf.props({ anything: 1 })
console.log(Stamp() instanceof Stamp) // true
console.log(Stamp().getStamp() === Stamp) // true
console.log(Stamp() instanceof InstanceOf) // false
console.log(InstanceOf() instanceof Stamp) // false
The above InstanceOf
stamp overrides the default instanceof
behavior using ES6 will-known symbol Symbol.hasInstance
. Compose it with your stamps if you need the instanceof
to work as expected for you.
NOTE
You can find the stamp above as the
@stamp/instanceof
NPM module.
The composers are concatenated into a deduplicated array. As the result, the order of composition becomes the order of composer execution.
const {composers} = stampit
const Log1 = composers(() => console.log(1))
const Log2 = composers(() => console.log(1))
const Log3 = composers(() => console.log(1))
const MultiLog = stampit(Log1, Log2, Log3)
MultiLog() // Will print three times:
// 1
// 1
// 1
// because there are 3 composers
MultiLog.compose.composers.length === 3
Stamps remove duplicate composers.
const {composers} = stampit
const func = () => console.log(1)
const Log1 = composers(func)
const Log2 = composers(func)
const Log3 = composers(func)
const MultiLog = stampit(Log1, Log2, Log3)
MultiLog() // Will print only once:
// 1
// because there is only one composer
MultiLog.compose.composers.length === 1
Every composer always receive this object: { stamp, composables }
. Where:
stamp
is the stamp which was used to create this object. Useful to retrieve stamp's metadata (aka descriptor).composables
is the array of stamps and descriptors the above stamp was composed with.
Exactly the same stamp can be created in few ways. Here they all are.
function myDebugComposer ({ stamp, composables }) {
console.log(`Stamp ${stamp} was composed of ${composables}`)
}
const Logger = stampit({
composers: myDebugComposer
})
const Logger = stampit({
composers: [myDebugComposer]
})
const Logger = stampit.composers(myDebugComposer)
const Logger = stampit.composers([myDebugComposer])
const Logger = stampit().composers(myDebugComposer)
const Logger = stampit().composers([myDebugComposer])