-
-
Notifications
You must be signed in to change notification settings - Fork 390
/
Copy pathModuleManager.js
161 lines (145 loc) · 3.94 KB
/
ModuleManager.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import {createStore} from 'redux';
import {DependencyError} from './errors';
/**
* @class ModuleManager
* @category core
* @param {Object} object handler
* @description Solves modules dependencies
* @memberof module:core
*/
export class ModuleManager {
constructor(object) {
this.handler = object;
this.currentModule = null;
this.store = createStore((state = [{}, ''], action) => {
state[0][action.key] = action.data;
state[1] = action.key;
return state;
});
this.modules = {};
}
/**
* @method active
* @instance
* @description Sets .currentModule to provided module.
* @param {Object} module the module to make current
* @memberof module:core.ModuleManager
*/
active(module) {
this.currentModule = module;
}
/**
* @method reset
* @instance
* @description Set's .currentModule to null.
* @memberof module:core.ModuleManager
*/
reset() {
this.currentModule = null;
}
/**
* @method define
* @instance
* @description Define the module in manager
* @param {String} name The module name
* @memberof module:core.ModuleManager
*/
define(name) {
this.modules[name] = this.currentModule;
}
/**
* @method use
* @instance
* @description Get the defined module from manager
* @param name The module name
* @memberof module:core.ModuleManager
*/
use(name) {
return this.modules[name];
}
/**
* @method set
* @instance
* @description An alias for .add() <br/><br/>
* Use this method if you know that you will overwrite existing dependency.<br/>
* Use it in your app, but not in module that you provide to other people.
* @param {String} key the key of the dependency
* @param {Object} data the value of the dependency
* @memberof module:core.ModuleManager
*/
set(key, data) {
this.store.dispatch({
type: 'ADD',
key,
data
});
}
/**
* @method get
* @instance
* @description Returns dependency in store object, by key.
* @param {String} key the key of the dependency
* @memberof module:core.ModuleManager
* @return {Object|Module}
* @throws {DependencyError} if dependency is not in the store
* @example <caption>Get the 'hello' dependency</caption>
* manager.get('hello'); // -> {world: true}
*/
get(key) {
if (!this.store.getState()[0][key]) {
throw new DependencyError(
'ModuleManager',
`Module requires '${key}' dependency`,
this.currentModule
);
}
return this.store.getState()[0][key];
}
/**
* @method has
* @instance
* @description Returns whether manager has a dependency with the given key
* @param {String} key the key of the dependency
* @memberof module:core.ModuleManager
* @return {Boolean} Promise that is resolved when all promises completed.
* @example <caption>Check whether the store has the 'hello' dependency</caption>
* manager.has('hello'); // -> true
*/
has(key) {
return Boolean(this.store.getState()[0][key]);
}
/**
* @method update
* @instance
* @description Updates deps
* @param {Object} [depsMap={}]
* @memberof module:core.ModuleManager
*/
update(depsMap = {}) {
this.store.subscribe(() => {
const [data, changedKey] = this.store.getState();
const callback = depsMap[changedKey];
if (callback) callback(data[changedKey]);
});
}
/**
* @method add
* @alias module:core.ModuleManager#set
* @memberof module:core.ModuleManager
*/
add(...data) {
console.warn('.add() method is deprecated. Use .set() instead');
return this.set(...data);
}
/**
* @method require
* @instance
* @description Require module
* @param {String} name Defined name
* @param {Function} moduleExecutor Function that returns applied module
* @memberof module:core.ModuleManager
*/
require(name, moduleExecutor) {
if (this.use(name) === undefined) this.handler.applyModule(moduleExecutor());
}
}