-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathshowcase.js
72 lines (63 loc) · 2.02 KB
/
showcase.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
const { createClass, reflect, provider, inject } = require('.');
// Log advice. This advice logs all info within the called method
const Log = reflect.advice(function(meta){
console.info(`${meta.key} method called with
${JSON.stringify(meta.args)} returned ${meta.result}`);
});
// ChargeBean advice. if the first argument is truthy, next
// function will be delayed 100ms
const ChargeBean = reflect.advice(function(meta){
if(!meta.args[0]) {
meta.commit();
} else {
console.info("charging the beam...");
setTimeout(meta.commit, 100);
}
});
// create a provider of Beam class
const BeamProvider = provider.factory(createClass({
use(beamType) {
return `firing ${beamType}`;
}
}));
// LoggerAspect applies Log advice to every method
const LoggerAspect = reflect.aspect((currentProps, key) => {
if(currentProps[key] instanceof Function) {
currentProps[key] = [currentProps[key], Log];
} else if(currentProps[key] instanceof Array) {
currentProps[key].push(Log);
}
return currentProps;
});
// SomersaultAspect adds `doSommersault` method
const SomersaultAspect = reflect.aspect((currentProps, key) => {
if(typeof currentProps.doSommersault !== "function") {
currentProps.doSommersault = function() {
return `${this.name} performing a somersault!`;
}
}
return currentProps;
})
// create an Human class with LoggerAspect and SomersaultAspect
// and we apply ChargeBean advice directly to `fire` method
const Human = createClass(
LoggerAspect(SomersaultAspect({
// inject beam instance on $beam property before
// main constructor gets executed
constructor: [inject.assign({ $beam: BeamProvider }), function(_name){
this.name = _name;
}],
fire: [ChargeBean, function(charging, fireType) {
return this.$beam.use(fireType);
}],
sayHello() {
return `Hey, I'm ${this.name}`;
}
}))
);
const human = new Human("Samus Aran");
human.sayHello();
human.doSommersault();
human.fire(false, "normal");
human.fire(false, "ice");
human.fire(true, "plasma");