-
Notifications
You must be signed in to change notification settings - Fork 3
/
TargetExposition.js
109 lines (102 loc) · 2.86 KB
/
TargetExposition.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
const map = require('./map');
/**
* Exposes some properties of target object into computed properties compatible bunch
* of getters or/and setters
*/
class TargetExposition {
/**
*
* @param {Target} target
* @param {Array} projection
*/
constructor(target, projection) {
this.target = target;
this.projection = projection;
this.sendTarget = false;
}
/**
* Sets `mutation` to be commited on exposed field change
* if `sendTarget` is `false`, `action` shall be called in format:
*
* `commit(mutation, { key, value })`
*
* otherwise, if `sendTarget` is set to `true`
*
* `commit(mutation, { target, key, value })`
*
* **Hint**: That's just syntax sugar for `hook()` method.
* @param {String} mutation name of mutation
* @param {Boolean} sendTarget send target to action
* @return {TargetExposition}
*/
commit(mutation, sendTarget = false) {
this.target.commit(mutation);
this.sendTarget = sendTarget || false;
return this;
}
/**
* Sets `action` to be dispatched on exposed field change.
* if `sendTarget` is `false`, `action` shall be called in format:
*
* `dispatch(action, { key, value })`
*
* otherwise, if `sendTarget` is set to `true`
*
* `dispatch(action, { target, key, value })`
*
* **Hint**: That's just syntax sugar for `hook()` method.
* @param {String} action name of action
* @param {Boolean} sendTarget send target to action
* @return {TargetExposition}
*/
dispatch(action, sendTarget = false) {
this.target.dispatch(action);
this.sendTarget = sendTarget || false;
return this;
}
/**
* set callback to be run on property change
*
* @param {TargetExposition~dispatcher} dispatcher
* @param {Boolean} sendTarget
* @return {TargetExposition}
*/
hook(dispatcher, sendTarget) {
this.target.hook(dispatcher);
this.sendTarget = sendTarget || false;
return this;
}
/**
* @callback TargetExposition~dispatcher
* @param {Store} store `vuex` store
* @param {*} value changed value
* @param {String} key key of changed field
* @param {*} target parent object of changed field
*/
/**
* generates map of getters or/and setters for specified projection
*
* @return {Object}
*/
map() {
const result = {};
const { target, sendTarget } = this;
this.projection.forEach(field => {
let camelCasedField = (field.indexOf('.') === -1) ? field : field.replace(/\.(.)/g, (all, matched) => matched.toUpperCase());
result[camelCasedField] = map(target, field, sendTarget);
});
if (target.inject) Object.assign(result, target.inject);
return result;
}
/**
* look [Target.use(plugin)](#Target+use)
*
* @param plugin
* @return {TargetExposition}
*/
use(plugin) {
this.target.use(plugin);
return this;
}
}
module.exports = TargetExposition;