@quazardous/quarkernel 1.0.9 → 1.0.11
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/README.md +12 -7
- package/package.json +1 -1
- package/src/lib/QuarKernel.js +64 -16
- package/types/QuarKernel.d.ts +11 -6
package/README.md
CHANGED
|
@@ -6,11 +6,16 @@ Micro Custom Event Kernel.
|
|
|
6
6
|
|
|
7
7
|
Helps structuring your app with events.
|
|
8
8
|
|
|
9
|
-
- ES6
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
|
|
9
|
+
- Modern: ES6, Async() support with Promise
|
|
10
|
+
- Dependency support: easily handle async resource dependencies
|
|
11
|
+
- Composite event: handle complex logic with a common event pipe
|
|
12
|
+
- Shared context: use event data to share variable
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm i "@quazardous/quarkernel"
|
|
18
|
+
```
|
|
14
19
|
|
|
15
20
|
## Basic usage
|
|
16
21
|
|
|
@@ -34,14 +39,14 @@ qk.addEventListener('my_event', async (e) => {
|
|
|
34
39
|
e.context.needed = await needed();
|
|
35
40
|
}, 'foo');
|
|
36
41
|
|
|
37
|
-
// somewhere else in your app your module bar is
|
|
42
|
+
// somewhere else in your app your module bar is waiting after foo to set a specific context
|
|
38
43
|
qk.addEventListener('my_event', (e) => {
|
|
39
44
|
// something after the async callback
|
|
40
45
|
needing(e.context.needed);
|
|
41
46
|
}, 'bar', 'foo');
|
|
42
47
|
|
|
43
48
|
// call everything
|
|
44
|
-
qk.dispatchEvent(new QKE('my_event')).then(() => {
|
|
49
|
+
qk.dispatchEvent(new QKE('my_event')).then((e) => {
|
|
45
50
|
// event my_event fully dispatched
|
|
46
51
|
happyEnd();
|
|
47
52
|
});
|
package/package.json
CHANGED
package/src/lib/QuarKernel.js
CHANGED
|
@@ -2,10 +2,28 @@
|
|
|
2
2
|
import toposort from 'toposort';
|
|
3
3
|
|
|
4
4
|
class GraphNode {
|
|
5
|
+
/**
|
|
6
|
+
* @param {string} target
|
|
7
|
+
* @param {string} name
|
|
8
|
+
* @param {Array<string>} requires
|
|
9
|
+
* @param {eventListenerCallback|async eventListenerCallback} callback
|
|
10
|
+
*/
|
|
5
11
|
constructor(target, name, requires, callback) {
|
|
12
|
+
/**
|
|
13
|
+
* @type {string}
|
|
14
|
+
*/
|
|
6
15
|
this.target = target;
|
|
16
|
+
/**
|
|
17
|
+
* @type {string}
|
|
18
|
+
*/
|
|
7
19
|
this.name = name;
|
|
20
|
+
/**
|
|
21
|
+
* @type {Array<string>}
|
|
22
|
+
*/
|
|
8
23
|
this.requires = requires;
|
|
24
|
+
/**
|
|
25
|
+
* @type {eventListenerCallback|async eventListenerCallback}
|
|
26
|
+
*/
|
|
9
27
|
this.callback = callback;
|
|
10
28
|
}
|
|
11
29
|
}
|
|
@@ -15,7 +33,13 @@ class GraphNodeProcessor {
|
|
|
15
33
|
* @param {Array<GraphNode>} nodes
|
|
16
34
|
*/
|
|
17
35
|
constructor(nodes) {
|
|
36
|
+
/**
|
|
37
|
+
* @type {Object.<string, {promise:Promise<QuarKernelEvent>|null,node:GraphNode}>}
|
|
38
|
+
*/
|
|
18
39
|
this.processMap = {};
|
|
40
|
+
/**
|
|
41
|
+
* @type {Array<GraphNode>} nodes
|
|
42
|
+
*/
|
|
19
43
|
this.nodes = nodes;
|
|
20
44
|
nodes.forEach(n => {
|
|
21
45
|
this.processMap[n.name] = {
|
|
@@ -25,35 +49,53 @@ class GraphNodeProcessor {
|
|
|
25
49
|
});
|
|
26
50
|
}
|
|
27
51
|
|
|
28
|
-
|
|
52
|
+
/**
|
|
53
|
+
* @param {QuarKernelEvent} e
|
|
54
|
+
* @return {Promise<QuarKernelEvent>}
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
processAll(e) {
|
|
29
58
|
return Promise.all(
|
|
30
|
-
this.nodes.map(n => this.process(n,
|
|
31
|
-
);
|
|
59
|
+
this.nodes.map(n => this.process(n, e))
|
|
60
|
+
).then(() => e);
|
|
32
61
|
}
|
|
33
62
|
|
|
34
|
-
|
|
63
|
+
/**
|
|
64
|
+
* @param {GraphNode} node
|
|
65
|
+
* @param {QuarKernelEvent} e
|
|
66
|
+
* @return {Promise<*>}
|
|
67
|
+
* @private
|
|
68
|
+
*/
|
|
69
|
+
process(node, e) {
|
|
35
70
|
const process = this.processMap[node.name];
|
|
36
71
|
if (!process.promise) {
|
|
37
72
|
let then = null;
|
|
38
73
|
if (node.callback.constructor.name === 'AsyncFunction') {
|
|
39
74
|
// handle async
|
|
40
|
-
then = () => node.callback(
|
|
75
|
+
then = () => node.callback(e, node.target);
|
|
41
76
|
} else {
|
|
42
77
|
then = () => new Promise((resolve) => {
|
|
43
|
-
|
|
78
|
+
node.callback(e, node.target);
|
|
79
|
+
resolve();
|
|
44
80
|
});
|
|
45
81
|
}
|
|
46
|
-
process.promise = this.processDependencies(node,
|
|
82
|
+
process.promise = this.processDependencies(node, e).then(then);
|
|
47
83
|
}
|
|
48
84
|
return process.promise;
|
|
49
85
|
}
|
|
50
86
|
|
|
51
|
-
|
|
87
|
+
/**
|
|
88
|
+
* @param {GraphNode} node
|
|
89
|
+
* @param {QuarKernelEvent} e
|
|
90
|
+
* @return {Promise<*>}
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
processDependencies(node, e) {
|
|
52
94
|
if (node.requires.length) {
|
|
53
95
|
const promises = [];
|
|
54
96
|
this.nodes.forEach(n => {
|
|
55
97
|
if (node.requires.includes(n.target)) {
|
|
56
|
-
promises.push(this.process(n,
|
|
98
|
+
promises.push(this.process(n, e));
|
|
57
99
|
}
|
|
58
100
|
});
|
|
59
101
|
return Promise.all(promises);
|
|
@@ -94,7 +136,7 @@ class CompositeTrigger {
|
|
|
94
136
|
this.callback = callback;
|
|
95
137
|
this.reset = reset;
|
|
96
138
|
/**
|
|
97
|
-
* @type {Object.<string, Array<{e:QuarKernelEvent,p:Promise
|
|
139
|
+
* @type {Object.<string, Array<{e:QuarKernelEvent,p:Promise<QuarKernelEvent>}>>}
|
|
98
140
|
*/
|
|
99
141
|
this.eventPromiseStack = {};
|
|
100
142
|
}
|
|
@@ -103,6 +145,7 @@ class CompositeTrigger {
|
|
|
103
145
|
* @param {QuarKernelEvent} e
|
|
104
146
|
* @param {Promise<*>} p
|
|
105
147
|
* @return {Promise<*>|null}
|
|
148
|
+
* @private
|
|
106
149
|
*/
|
|
107
150
|
compose(e, p) {
|
|
108
151
|
if (!this.components.includes(e.type)) {
|
|
@@ -135,9 +178,14 @@ class CompositeTrigger {
|
|
|
135
178
|
}
|
|
136
179
|
}
|
|
137
180
|
|
|
181
|
+
/**
|
|
182
|
+
* @callback eventListenerCallback
|
|
183
|
+
* @param {QuarKernelEvent} [e]
|
|
184
|
+
*/
|
|
185
|
+
|
|
138
186
|
/**
|
|
139
187
|
* @callback composeTriggerCallback
|
|
140
|
-
* @param {Object.<string, Array<{e:QuarKernelEvent,p:Promise
|
|
188
|
+
* @param {Object.<string, Array<{e:QuarKernelEvent,p:Promise<QuarKernelEvent>}>>} [stack] Stack of components events/promises
|
|
141
189
|
*/
|
|
142
190
|
|
|
143
191
|
/**
|
|
@@ -260,8 +308,8 @@ class QuarKernel {
|
|
|
260
308
|
|
|
261
309
|
/**
|
|
262
310
|
* @param {QuarKernelEvent} e
|
|
263
|
-
* @param {Promise
|
|
264
|
-
* @return {Promise
|
|
311
|
+
* @param {Promise<QuarKernelEvent>} p
|
|
312
|
+
* @return {Promise<QuarKernelEvent>}
|
|
265
313
|
* @private
|
|
266
314
|
*/
|
|
267
315
|
composeTrigger(e, p) {
|
|
@@ -273,7 +321,7 @@ class QuarKernel {
|
|
|
273
321
|
}
|
|
274
322
|
});
|
|
275
323
|
if (list.length > 0) {
|
|
276
|
-
p = p.then(() => Promise.all(list))
|
|
324
|
+
p = p.then(() => Promise.all(list).then(() => e))
|
|
277
325
|
}
|
|
278
326
|
return p;
|
|
279
327
|
}
|
|
@@ -282,7 +330,7 @@ class QuarKernel {
|
|
|
282
330
|
* Dispatch an event.
|
|
283
331
|
*
|
|
284
332
|
* @param {QuarKernelEvent} e The event
|
|
285
|
-
* @return {Promise
|
|
333
|
+
* @return {Promise<QuarKernelEvent>}
|
|
286
334
|
*/
|
|
287
335
|
dispatchEvent(e) {
|
|
288
336
|
if (!(e instanceof QuarKernelEvent)) {
|
|
@@ -290,7 +338,7 @@ class QuarKernel {
|
|
|
290
338
|
}
|
|
291
339
|
if (typeof this.callbacks[e.type] === 'undefined') {
|
|
292
340
|
// no callback registered
|
|
293
|
-
return this.composeTrigger(e, Promise.resolve());
|
|
341
|
+
return this.composeTrigger(e, Promise.resolve(e));
|
|
294
342
|
}
|
|
295
343
|
if (typeof this.seqGraph[e.type] !== 'undefined') {
|
|
296
344
|
// using toposort to early detect dependencies loop
|
package/types/QuarKernel.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
export type eventListenerCallback = (e?: QuarKernelEvent) => any;
|
|
1
2
|
export type composeTriggerCallback = (stack?: {
|
|
2
3
|
[x: string]: Array<{
|
|
3
4
|
e: QuarKernelEvent;
|
|
4
|
-
p: Promise<
|
|
5
|
+
p: Promise<QuarKernelEvent>;
|
|
5
6
|
}>;
|
|
6
7
|
}) => any;
|
|
7
8
|
export type composeEventFactory = (stack?: {
|
|
@@ -9,9 +10,13 @@ export type composeEventFactory = (stack?: {
|
|
|
9
10
|
}) => QuarKernelEvent;
|
|
10
11
|
export type eventCallback = (e?: QuarKernelEvent, target?: string) => any;
|
|
11
12
|
export type eventAsyncCallback = () => any;
|
|
13
|
+
/**
|
|
14
|
+
* @callback eventListenerCallback
|
|
15
|
+
* @param {QuarKernelEvent} [e]
|
|
16
|
+
*/
|
|
12
17
|
/**
|
|
13
18
|
* @callback composeTriggerCallback
|
|
14
|
-
* @param {Object.<string, Array<{e:QuarKernelEvent,p:Promise
|
|
19
|
+
* @param {Object.<string, Array<{e:QuarKernelEvent,p:Promise<QuarKernelEvent>}>>} [stack] Stack of components events/promises
|
|
15
20
|
*/
|
|
16
21
|
/**
|
|
17
22
|
* @callback composeEventFactory
|
|
@@ -84,8 +89,8 @@ export class QuarKernel {
|
|
|
84
89
|
addCompositeEvent(components: Array<string>, factory: composeEventFactory, reset?: boolean): void;
|
|
85
90
|
/**
|
|
86
91
|
* @param {QuarKernelEvent} e
|
|
87
|
-
* @param {Promise
|
|
88
|
-
* @return {Promise
|
|
92
|
+
* @param {Promise<QuarKernelEvent>} p
|
|
93
|
+
* @return {Promise<QuarKernelEvent>}
|
|
89
94
|
* @private
|
|
90
95
|
*/
|
|
91
96
|
private composeTrigger;
|
|
@@ -93,9 +98,9 @@ export class QuarKernel {
|
|
|
93
98
|
* Dispatch an event.
|
|
94
99
|
*
|
|
95
100
|
* @param {QuarKernelEvent} e The event
|
|
96
|
-
* @return {Promise
|
|
101
|
+
* @return {Promise<QuarKernelEvent>}
|
|
97
102
|
*/
|
|
98
|
-
dispatchEvent(e: QuarKernelEvent): Promise<
|
|
103
|
+
dispatchEvent(e: QuarKernelEvent): Promise<QuarKernelEvent>;
|
|
99
104
|
/**
|
|
100
105
|
* @param {string} type
|
|
101
106
|
* @param {string} target
|