Mixins and with
¶
As things are just a combination of types and capabilities in there is support
for combining them built in to the core library. Thing
provides a method
with
that mixes several types and capabilities together:
class CustomThing extends Thing.with(Mixin1, Mixin2) {
...
}
Defining a mixin¶
Mixins are defined via Thing.mixin
and they work the same as a normal
Thing
-class such as with metadata. Mixins are functions
that create a JavaScript class with a specific parent:
const { Thing } = require('abstract-things');
const CustomMixin = Thing.mixin(Parent => class extends Parent {
static get capability() {
return 'custom:cap';
}
constructor(...args) {
// Most mixins should call super with all arguments
super(...args);
// Set properties, initialize event listeners as normal
this.custom = true;
}
customMethod() {
return this.custom;
}
});
Internal capabilities¶
In some cases when building a library things will be very straight-forward,
just extend Thing
with whatever is needed, implement the behavior and
abstract methods and you’re done. In other cases such as when working against
a IoT-bridge for things such as lights or sensors you might find that its
useful to package the API used to talk to the thing as an internal capability.
Example:
const { Thing } = require('abstract-things');
const { Light, SwitchablePower } = require('abstract-things/light');
// This mixin provides access to the external API for custom capabilities
const CustomAPI = Thing.mixin(Parent => class extends Parent {
constructor(api) {
super();
this.api = api;
}
initCallback() {
return super.initCallback()
// Ask the fake API to initialize itself
.then(() => this.api.init());
}
});
/*
* Create the custom capability that provides an implementation of
* SwitchablePower on top of CustomAPI.
*/
const CustomPower = Thing.mixin(Parent => class extends Parent
.with(CustomAPI, SwitchablePower) {
initCallback() {
return super.initCallback()
.then(() => {
// During init this connects to the powerChanged event of our fake API
this.api.on('powerChanged', power => this.updatePower(power))
// Set the power as well
this.updatePower(this.api.hasPower());
});
}
updatePower(power) {
return this.api.setPower(power);
}
});
const CustomDimmable = ...;
// Define the specific combinations that can exist
const PoweredThing = Light.with(CustomPower);
const PoweredAndDimambleThing = Light.with(CustomPower, CustomDimmable);
// Create them and pass the API-instance
new PoweredThing(getApiSomehow());