@quazardous/quarkernel 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +69 -0
- package/package.json +38 -0
- package/src/index.js +3 -0
- package/src/lib/QuarKernel.js +342 -0
- package/types/QuarKernel.d.ts +117 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 quazardous
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# QuarKernel
|
|
2
|
+
|
|
3
|
+
Micro Custom Event Kernel.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
Helps structuring your app with events.
|
|
8
|
+
|
|
9
|
+
- ES6
|
|
10
|
+
- Async() support with Promise
|
|
11
|
+
- Event scope dependency support
|
|
12
|
+
- Composite event
|
|
13
|
+
- Shared context
|
|
14
|
+
|
|
15
|
+
## Basic usage
|
|
16
|
+
|
|
17
|
+
Define event listeners across your app modules with dependency support.
|
|
18
|
+
Share context between components.
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import { QuarKernel, QuarKernelEvent as QKE } from '@quazardous/quarkernel';
|
|
22
|
+
|
|
23
|
+
// singleton
|
|
24
|
+
const qk = new QuarKernel();
|
|
25
|
+
|
|
26
|
+
qk.addEventListener('my_event', (e) => {
|
|
27
|
+
// something
|
|
28
|
+
notNeeded();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// your module foo does some init stuff
|
|
32
|
+
qk.addEventListener('my_event', async (e) => {
|
|
33
|
+
// something async
|
|
34
|
+
e.context.needed = await needed();
|
|
35
|
+
}, 'foo');
|
|
36
|
+
|
|
37
|
+
// somewhere else in your app your module bar is waitint after foo to set a specific context
|
|
38
|
+
qk.addEventListener('my_event', (e) => {
|
|
39
|
+
// something after the async callback
|
|
40
|
+
needing(e.context.needed);
|
|
41
|
+
}, 'bar', 'foo');
|
|
42
|
+
|
|
43
|
+
// call everything
|
|
44
|
+
qk.dispatchEvent(new QKE('my_event')).then(() => {
|
|
45
|
+
// event my_event fully dispatched
|
|
46
|
+
happyEnd();
|
|
47
|
+
});
|
|
48
|
+
// or await qk.dispatchEvent(new QKE('my_event'));
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Composite event
|
|
52
|
+
|
|
53
|
+
Composite event are auto dispatched when a specific list of events are dispatched.
|
|
54
|
+
|
|
55
|
+
ie. You set a composite event C on A+B. Your code dispatches A, then B. C is auto dispatched after B.
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
...
|
|
59
|
+
// init
|
|
60
|
+
qk.addCompositeEvent(['A','B'], (stack) => new QKE('C'));
|
|
61
|
+
...
|
|
62
|
+
qk.dispatchEvent(new QKE('A'));
|
|
63
|
+
...
|
|
64
|
+
// this will auto dispatch C
|
|
65
|
+
qk.dispatchEvent(new QKE('B'));
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@quazardous/quarkernel",
|
|
3
|
+
"version": "1.0.9",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Micro Custom Events Kernel",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/quazardous/quarkernel.git"
|
|
9
|
+
},
|
|
10
|
+
"module": "src/index.js",
|
|
11
|
+
"main": "src/index.js",
|
|
12
|
+
"files": [
|
|
13
|
+
"src/",
|
|
14
|
+
"types/"
|
|
15
|
+
],
|
|
16
|
+
"typings": "./types/QuarKernel.d.ts",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"prepare": "npm run gen-typings",
|
|
19
|
+
"test": "mocha tests/",
|
|
20
|
+
"gen-typings": "npx -p typescript tsc src/lib/*.js --declaration --allowJs --emitDeclarationOnly --outDir types"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"event",
|
|
24
|
+
"kernel",
|
|
25
|
+
"promise"
|
|
26
|
+
],
|
|
27
|
+
"author": "quazardous <berliozdavid@gmail.com>",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@babel/register": "^7.22.5",
|
|
31
|
+
"chai": "^4.3.7",
|
|
32
|
+
"core-js": "^3.29.1",
|
|
33
|
+
"mocha": "^9.2.0"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"toposort": "^2.0.2"
|
|
37
|
+
}
|
|
38
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/* eslint-disable no-plusplus */
|
|
2
|
+
import toposort from 'toposort';
|
|
3
|
+
|
|
4
|
+
class GraphNode {
|
|
5
|
+
constructor(target, name, requires, callback) {
|
|
6
|
+
this.target = target;
|
|
7
|
+
this.name = name;
|
|
8
|
+
this.requires = requires;
|
|
9
|
+
this.callback = callback;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class GraphNodeProcessor {
|
|
14
|
+
/**
|
|
15
|
+
* @param {Array<GraphNode>} nodes
|
|
16
|
+
*/
|
|
17
|
+
constructor(nodes) {
|
|
18
|
+
this.processMap = {};
|
|
19
|
+
this.nodes = nodes;
|
|
20
|
+
nodes.forEach(n => {
|
|
21
|
+
this.processMap[n.name] = {
|
|
22
|
+
promise: null,
|
|
23
|
+
node: n
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
processAll(...args) {
|
|
29
|
+
return Promise.all(
|
|
30
|
+
this.nodes.map(n => this.process(n, ...args))
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
process(node, ...args) {
|
|
35
|
+
const process = this.processMap[node.name];
|
|
36
|
+
if (!process.promise) {
|
|
37
|
+
let then = null;
|
|
38
|
+
if (node.callback.constructor.name === 'AsyncFunction') {
|
|
39
|
+
// handle async
|
|
40
|
+
then = () => node.callback(...args, node.target);
|
|
41
|
+
} else {
|
|
42
|
+
then = () => new Promise((resolve) => {
|
|
43
|
+
resolve(node.callback(...args, node.target));
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
process.promise = this.processDependencies(node, ...args).then(then);
|
|
47
|
+
}
|
|
48
|
+
return process.promise;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
processDependencies(node, ...args) {
|
|
52
|
+
if (node.requires.length) {
|
|
53
|
+
const promises = [];
|
|
54
|
+
this.nodes.forEach(n => {
|
|
55
|
+
if (node.requires.includes(n.target)) {
|
|
56
|
+
promises.push(this.process(n, ...args));
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return Promise.all(promises);
|
|
60
|
+
}
|
|
61
|
+
return Promise.resolve();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
class QuarKernelEvent {
|
|
66
|
+
/**
|
|
67
|
+
* @param {string} type Type of the event
|
|
68
|
+
* @param {Object} [param] Parameters for this event
|
|
69
|
+
* @param {Object} [context] Modifiable context for this event
|
|
70
|
+
*/
|
|
71
|
+
constructor(type, param, context) {
|
|
72
|
+
this.type = type;
|
|
73
|
+
this.param = param || {};
|
|
74
|
+
this.context = context || {};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// /**
|
|
79
|
+
// * @typedef {Object} Person
|
|
80
|
+
// * @property {string} name how the person is called
|
|
81
|
+
// * @property {number} age how many years the person lived
|
|
82
|
+
// */
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
class CompositeTrigger {
|
|
88
|
+
/**
|
|
89
|
+
* @param {Array<string>} components
|
|
90
|
+
* @param {*} callback
|
|
91
|
+
*/
|
|
92
|
+
constructor(components, callback, reset) {
|
|
93
|
+
this.components = components;
|
|
94
|
+
this.callback = callback;
|
|
95
|
+
this.reset = reset;
|
|
96
|
+
/**
|
|
97
|
+
* @type {Object.<string, Array<{e:QuarKernelEvent,p:Promise<*>}>>}
|
|
98
|
+
*/
|
|
99
|
+
this.eventPromiseStack = {};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @param {QuarKernelEvent} e
|
|
104
|
+
* @param {Promise<*>} p
|
|
105
|
+
* @return {Promise<*>|null}
|
|
106
|
+
*/
|
|
107
|
+
compose(e, p) {
|
|
108
|
+
if (!this.components.includes(e.type)) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (typeof this.eventPromiseStack[e.type] === 'undefined') {
|
|
112
|
+
this.eventPromiseStack[e.type] = [];
|
|
113
|
+
}
|
|
114
|
+
this.eventPromiseStack[e.type].push({e, p});
|
|
115
|
+
|
|
116
|
+
let allComponents = true;
|
|
117
|
+
this.components.forEach((type) => {
|
|
118
|
+
if (typeof this.eventPromiseStack[e.type] === 'undefined') {
|
|
119
|
+
allComponents = false;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
if (!allComponents) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// we got all components !
|
|
128
|
+
const stack = this.eventPromiseStack;
|
|
129
|
+
if (this.reset) {
|
|
130
|
+
this.eventPromiseStack = {};
|
|
131
|
+
}
|
|
132
|
+
return new Promise((resolve) => {
|
|
133
|
+
resolve(this.callback(stack));
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @callback composeTriggerCallback
|
|
140
|
+
* @param {Object.<string, Array<{e:QuarKernelEvent,p:Promise<*>}>>} [stack] Stack of components events/promises
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @callback composeEventFactory
|
|
145
|
+
* @param {Object.<string, Array<QuarKernelEvent>>} [stack] Stack of components events
|
|
146
|
+
* @return {QuarKernelEvent}
|
|
147
|
+
*/
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @callback eventCallback
|
|
151
|
+
* @param {QuarKernelEvent} [e] The event
|
|
152
|
+
* @param {string} [target] The current target
|
|
153
|
+
*/
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @callback eventAsyncCallback
|
|
157
|
+
* @async
|
|
158
|
+
* @param {QuarKernelEvent} [e] The event
|
|
159
|
+
* @param {string} [target] The current target
|
|
160
|
+
*/
|
|
161
|
+
|
|
162
|
+
class QuarKernel {
|
|
163
|
+
constructor(options = {}) {
|
|
164
|
+
/**
|
|
165
|
+
* For each event type, list of valid target sequences.
|
|
166
|
+
* ie sequence [A, B] means A must be fired before B.
|
|
167
|
+
* @type {Array<string,Array<Array<string>>>}
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
this.seqGraph = {};
|
|
171
|
+
/**
|
|
172
|
+
* For each event type and target list of direct targets dependencies.
|
|
173
|
+
* @type {Array<string,Array<string,Array<string>>>}
|
|
174
|
+
* @private
|
|
175
|
+
*/
|
|
176
|
+
this.dependencies = {};
|
|
177
|
+
/**
|
|
178
|
+
* @type {Array<string,Array<string,Array<eventCallback|eventAsyncCallback>>}
|
|
179
|
+
* @private
|
|
180
|
+
*/
|
|
181
|
+
this.callbacks = {};
|
|
182
|
+
/**
|
|
183
|
+
* @private
|
|
184
|
+
*/
|
|
185
|
+
this.targetAutoId = 0;
|
|
186
|
+
/**
|
|
187
|
+
* @type {Array<CompositeTrigger>}
|
|
188
|
+
* @private
|
|
189
|
+
*/
|
|
190
|
+
this.compositeTriggers = [];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Register for some event.
|
|
195
|
+
*
|
|
196
|
+
* @param {string} type Type of event to listen to
|
|
197
|
+
* @param {eventCallback|eventAsyncCallback} callback
|
|
198
|
+
* @param {string} [target] A unique code for the target listener
|
|
199
|
+
* @param {string|Array<string>} [dependencies] A list of targets dependencies
|
|
200
|
+
* In the event scope, callbacks will be fired according to dependencies
|
|
201
|
+
*/
|
|
202
|
+
addEventListener(type, callback, target, dependencies = []) {
|
|
203
|
+
if (!target) {
|
|
204
|
+
target = `.auto.${this.targetAutoId}`;
|
|
205
|
+
this.targetAutoId++;
|
|
206
|
+
}
|
|
207
|
+
let deps = dependencies;
|
|
208
|
+
if (!Array.isArray(deps)) {
|
|
209
|
+
deps = [deps];
|
|
210
|
+
}
|
|
211
|
+
if (typeof this.seqGraph[type] === 'undefined') {
|
|
212
|
+
this.seqGraph[type] = [];
|
|
213
|
+
}
|
|
214
|
+
deps.forEach((dep) => {
|
|
215
|
+
this.seqGraph[type].push([dep, target]);
|
|
216
|
+
});
|
|
217
|
+
if (typeof this.callbacks[type] === 'undefined') {
|
|
218
|
+
this.callbacks[type] = {};
|
|
219
|
+
}
|
|
220
|
+
if (typeof this.callbacks[type][target] === 'undefined') {
|
|
221
|
+
this.callbacks[type][target] = [];
|
|
222
|
+
}
|
|
223
|
+
this.callbacks[type][target].push(callback);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Create a composite trigger.
|
|
228
|
+
*
|
|
229
|
+
* @param {Array<string>} components list of event types
|
|
230
|
+
* @param {composeTriggerCallback} callback something to do
|
|
231
|
+
*/
|
|
232
|
+
addCompositeTrigger(components, callback, reset = true) {
|
|
233
|
+
this.compositeTriggers.push(new CompositeTrigger(components, callback, reset));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Create a composite event.
|
|
238
|
+
*
|
|
239
|
+
* @param {Array<string>} components list of event types
|
|
240
|
+
* @param {composeEventFactory} factory event factory
|
|
241
|
+
*/
|
|
242
|
+
addCompositeEvent(components, factory, reset = true) {
|
|
243
|
+
this.addCompositeTrigger(components, (stack) => {
|
|
244
|
+
const eventStack = {};
|
|
245
|
+
const list = [];
|
|
246
|
+
for (const type in stack) {
|
|
247
|
+
eventStack[type] = [];
|
|
248
|
+
stack[type].forEach((item) => {
|
|
249
|
+
list.push(item.p);
|
|
250
|
+
eventStack[type].push(item.e);
|
|
251
|
+
})
|
|
252
|
+
}
|
|
253
|
+
const self = this;
|
|
254
|
+
Promise.all(list).then(() => {
|
|
255
|
+
// dispatch after all event promises
|
|
256
|
+
self.dispatchEvent(factory(eventStack));
|
|
257
|
+
});
|
|
258
|
+
}, reset);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* @param {QuarKernelEvent} e
|
|
263
|
+
* @param {Promise<*>} p
|
|
264
|
+
* @return {Promise<*>}
|
|
265
|
+
* @private
|
|
266
|
+
*/
|
|
267
|
+
composeTrigger(e, p) {
|
|
268
|
+
const list = [];
|
|
269
|
+
this.compositeTriggers.forEach((ct) => {
|
|
270
|
+
const ctp = ct.compose(e, p);
|
|
271
|
+
if (ctp) {
|
|
272
|
+
list.push(ctp);
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
if (list.length > 0) {
|
|
276
|
+
p = p.then(() => Promise.all(list))
|
|
277
|
+
}
|
|
278
|
+
return p;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Dispatch an event.
|
|
283
|
+
*
|
|
284
|
+
* @param {QuarKernelEvent} e The event
|
|
285
|
+
* @return {Promise<*>}
|
|
286
|
+
*/
|
|
287
|
+
dispatchEvent(e) {
|
|
288
|
+
if (!(e instanceof QuarKernelEvent)) {
|
|
289
|
+
throw new Error('Not a QuarKernelEvent');
|
|
290
|
+
}
|
|
291
|
+
if (typeof this.callbacks[e.type] === 'undefined') {
|
|
292
|
+
// no callback registered
|
|
293
|
+
return this.composeTrigger(e, Promise.resolve());
|
|
294
|
+
}
|
|
295
|
+
if (typeof this.seqGraph[e.type] !== 'undefined') {
|
|
296
|
+
// using toposort to early detect dependencies loop
|
|
297
|
+
toposort(this.seqGraph[e.type]);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const nodes = [];
|
|
301
|
+
|
|
302
|
+
Object.keys(this.callbacks[e.type]).forEach((target) => {
|
|
303
|
+
this.callbacks[e.type][target].forEach((callback, i) => {
|
|
304
|
+
nodes.push(new GraphNode(
|
|
305
|
+
target,
|
|
306
|
+
`${target}.${i}`, // each callback gets a node
|
|
307
|
+
this.getTargetDependencies(e.type, target),
|
|
308
|
+
callback
|
|
309
|
+
));
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
return this.composeTrigger(e, (new GraphNodeProcessor(nodes)).processAll(e));
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* @param {string} type
|
|
318
|
+
* @param {string} target
|
|
319
|
+
* @return {Array<string>}
|
|
320
|
+
* @private
|
|
321
|
+
*/
|
|
322
|
+
getTargetDependencies(type, target) {
|
|
323
|
+
if (typeof this.dependencies[type] === 'undefined') {
|
|
324
|
+
this.dependencies[type] = {};
|
|
325
|
+
}
|
|
326
|
+
if (typeof this.dependencies[type][target] === 'undefined') {
|
|
327
|
+
this.dependencies[type][target] = [];
|
|
328
|
+
if (typeof this.seqGraph[type] !== 'undefined') {
|
|
329
|
+
this.seqGraph[type].forEach((seq) => {
|
|
330
|
+
if (seq[1] === target) {
|
|
331
|
+
this.dependencies[type][target].push(seq[0]);
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
// unique trick
|
|
335
|
+
this.dependencies[type][target] = [...new Set(this.dependencies[type][target])];
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return this.dependencies[type][target];
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export { QuarKernel, QuarKernelEvent };
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
export type composeTriggerCallback = (stack?: {
|
|
2
|
+
[x: string]: Array<{
|
|
3
|
+
e: QuarKernelEvent;
|
|
4
|
+
p: Promise<any>;
|
|
5
|
+
}>;
|
|
6
|
+
}) => any;
|
|
7
|
+
export type composeEventFactory = (stack?: {
|
|
8
|
+
[x: string]: Array<QuarKernelEvent>;
|
|
9
|
+
}) => QuarKernelEvent;
|
|
10
|
+
export type eventCallback = (e?: QuarKernelEvent, target?: string) => any;
|
|
11
|
+
export type eventAsyncCallback = () => any;
|
|
12
|
+
/**
|
|
13
|
+
* @callback composeTriggerCallback
|
|
14
|
+
* @param {Object.<string, Array<{e:QuarKernelEvent,p:Promise<*>}>>} [stack] Stack of components events/promises
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* @callback composeEventFactory
|
|
18
|
+
* @param {Object.<string, Array<QuarKernelEvent>>} [stack] Stack of components events
|
|
19
|
+
* @return {QuarKernelEvent}
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* @callback eventCallback
|
|
23
|
+
* @param {QuarKernelEvent} [e] The event
|
|
24
|
+
* @param {string} [target] The current target
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* @callback eventAsyncCallback
|
|
28
|
+
* @async
|
|
29
|
+
* @param {QuarKernelEvent} [e] The event
|
|
30
|
+
* @param {string} [target] The current target
|
|
31
|
+
*/
|
|
32
|
+
export class QuarKernel {
|
|
33
|
+
constructor(options?: {});
|
|
34
|
+
/**
|
|
35
|
+
* For each event type, list of valid target sequences.
|
|
36
|
+
* ie sequence [A, B] means A must be fired before B.
|
|
37
|
+
* @type {Array<string,Array<Array<string>>>}
|
|
38
|
+
* @private
|
|
39
|
+
*/
|
|
40
|
+
private seqGraph;
|
|
41
|
+
/**
|
|
42
|
+
* For each event type and target list of direct targets dependencies.
|
|
43
|
+
* @type {Array<string,Array<string,Array<string>>>}
|
|
44
|
+
* @private
|
|
45
|
+
*/
|
|
46
|
+
private dependencies;
|
|
47
|
+
/**
|
|
48
|
+
* @type {Array<string,Array<string,Array<eventCallback|eventAsyncCallback>>}
|
|
49
|
+
* @private
|
|
50
|
+
*/
|
|
51
|
+
private callbacks;
|
|
52
|
+
/**
|
|
53
|
+
* @private
|
|
54
|
+
*/
|
|
55
|
+
private targetAutoId;
|
|
56
|
+
/**
|
|
57
|
+
* @type {Array<CompositeTrigger>}
|
|
58
|
+
* @private
|
|
59
|
+
*/
|
|
60
|
+
private compositeTriggers;
|
|
61
|
+
/**
|
|
62
|
+
* Register for some event.
|
|
63
|
+
*
|
|
64
|
+
* @param {string} type Type of event to listen to
|
|
65
|
+
* @param {eventCallback|eventAsyncCallback} callback
|
|
66
|
+
* @param {string} [target] A unique code for the target listener
|
|
67
|
+
* @param {string|Array<string>} [dependencies] A list of targets dependencies
|
|
68
|
+
* In the event scope, callbacks will be fired according to dependencies
|
|
69
|
+
*/
|
|
70
|
+
addEventListener(type: string, callback: eventCallback | eventAsyncCallback, target?: string, dependencies?: string | Array<string>): void;
|
|
71
|
+
/**
|
|
72
|
+
* Create a composite trigger.
|
|
73
|
+
*
|
|
74
|
+
* @param {Array<string>} components list of event types
|
|
75
|
+
* @param {composeTriggerCallback} callback something to do
|
|
76
|
+
*/
|
|
77
|
+
addCompositeTrigger(components: Array<string>, callback: composeTriggerCallback, reset?: boolean): void;
|
|
78
|
+
/**
|
|
79
|
+
* Create a composite event.
|
|
80
|
+
*
|
|
81
|
+
* @param {Array<string>} components list of event types
|
|
82
|
+
* @param {composeEventFactory} factory event factory
|
|
83
|
+
*/
|
|
84
|
+
addCompositeEvent(components: Array<string>, factory: composeEventFactory, reset?: boolean): void;
|
|
85
|
+
/**
|
|
86
|
+
* @param {QuarKernelEvent} e
|
|
87
|
+
* @param {Promise<*>} p
|
|
88
|
+
* @return {Promise<*>}
|
|
89
|
+
* @private
|
|
90
|
+
*/
|
|
91
|
+
private composeTrigger;
|
|
92
|
+
/**
|
|
93
|
+
* Dispatch an event.
|
|
94
|
+
*
|
|
95
|
+
* @param {QuarKernelEvent} e The event
|
|
96
|
+
* @return {Promise<*>}
|
|
97
|
+
*/
|
|
98
|
+
dispatchEvent(e: QuarKernelEvent): Promise<any>;
|
|
99
|
+
/**
|
|
100
|
+
* @param {string} type
|
|
101
|
+
* @param {string} target
|
|
102
|
+
* @return {Array<string>}
|
|
103
|
+
* @private
|
|
104
|
+
*/
|
|
105
|
+
private getTargetDependencies;
|
|
106
|
+
}
|
|
107
|
+
export class QuarKernelEvent {
|
|
108
|
+
/**
|
|
109
|
+
* @param {string} type Type of the event
|
|
110
|
+
* @param {Object} [param] Parameters for this event
|
|
111
|
+
* @param {Object} [context] Modifiable context for this event
|
|
112
|
+
*/
|
|
113
|
+
constructor(type: string, param?: any, context?: any);
|
|
114
|
+
type: string;
|
|
115
|
+
param: any;
|
|
116
|
+
context: any;
|
|
117
|
+
}
|