@bluelibs/runner 1.3.0 → 1.5.0
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 +223 -82
- package/dist/defs.d.ts +41 -7
- package/dist/examples/express-mongo/index.d.ts +0 -0
- package/dist/examples/express-mongo/index.js +3 -0
- package/dist/examples/express-mongo/index.js.map +1 -0
- package/dist/globalEvents.js +1 -0
- package/dist/globalEvents.js.map +1 -1
- package/dist/models/DependencyProcessor.d.ts +7 -5
- package/dist/models/DependencyProcessor.js +46 -25
- package/dist/models/DependencyProcessor.js.map +1 -1
- package/dist/models/EventManager.d.ts +1 -1
- package/dist/models/EventManager.js +2 -2
- package/dist/models/EventManager.js.map +1 -1
- package/dist/models/Logger.d.ts +16 -11
- package/dist/models/Logger.js +29 -17
- package/dist/models/Logger.js.map +1 -1
- package/dist/models/ResourceInitializer.d.ts +3 -1
- package/dist/models/ResourceInitializer.js +10 -10
- package/dist/models/ResourceInitializer.js.map +1 -1
- package/dist/models/Store.d.ts +4 -1
- package/dist/models/Store.js +17 -3
- package/dist/models/Store.js.map +1 -1
- package/dist/models/TaskRunner.d.ts +3 -1
- package/dist/models/TaskRunner.js +13 -7
- package/dist/models/TaskRunner.js.map +1 -1
- package/dist/run.d.ts +0 -8
- package/dist/run.js +11 -8
- package/dist/run.js.map +1 -1
- package/package.json +3 -2
- package/src/__tests__/index.ts +1 -0
- package/src/__tests__/models/EventManager.test.ts +21 -21
- package/src/__tests__/models/Logger.test.ts +50 -5
- package/src/__tests__/models/ResourceInitializer.test.ts +61 -25
- package/src/__tests__/models/Store.test.ts +4 -2
- package/src/__tests__/models/TaskRunner.test.ts +5 -2
- package/src/__tests__/run.hooks.test.ts +0 -31
- package/src/__tests__/run.middleware.test.ts +26 -0
- package/src/__tests__/typesafety.test.ts +127 -0
- package/src/defs.ts +57 -15
- package/src/examples/express-mongo/index.ts +1 -0
- package/src/globalEvents.ts +1 -0
- package/src/models/DependencyProcessor.ts +103 -47
- package/src/models/EventManager.ts +4 -2
- package/src/models/Logger.ts +39 -19
- package/src/models/ResourceInitializer.ts +53 -27
- package/src/models/Store.ts +20 -3
- package/src/models/TaskRunner.ts +45 -18
- package/src/run.ts +19 -15
|
@@ -6,12 +6,13 @@ import {
|
|
|
6
6
|
IHookDefinition,
|
|
7
7
|
IEventDefinition,
|
|
8
8
|
} from "../defs";
|
|
9
|
-
import { ResourceStoreElementType, Store } from "./Store";
|
|
9
|
+
import { ResourceStoreElementType, Store, TaskStoreElementType } from "./Store";
|
|
10
10
|
import * as utils from "../define";
|
|
11
11
|
import { EventManager } from "./EventManager";
|
|
12
12
|
import { ResourceInitializer } from "./ResourceInitializer";
|
|
13
13
|
import { TaskRunner } from "./TaskRunner";
|
|
14
14
|
import { Errors } from "../errors";
|
|
15
|
+
import { Logger } from "./Logger";
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* This class is responsible of setting up dependencies with their respective computedValues.
|
|
@@ -24,9 +25,14 @@ export class DependencyProcessor {
|
|
|
24
25
|
constructor(
|
|
25
26
|
protected readonly store: Store,
|
|
26
27
|
protected readonly eventManager: EventManager,
|
|
27
|
-
protected readonly taskRunner: TaskRunner
|
|
28
|
+
protected readonly taskRunner: TaskRunner,
|
|
29
|
+
protected readonly logger: Logger
|
|
28
30
|
) {
|
|
29
|
-
this.resourceInitializer = new ResourceInitializer(
|
|
31
|
+
this.resourceInitializer = new ResourceInitializer(
|
|
32
|
+
store,
|
|
33
|
+
eventManager,
|
|
34
|
+
logger
|
|
35
|
+
);
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
/**
|
|
@@ -35,35 +41,59 @@ export class DependencyProcessor {
|
|
|
35
41
|
async computeAllDependencies() {
|
|
36
42
|
for (const middleware of this.store.middlewares.values()) {
|
|
37
43
|
const deps = middleware.middleware.dependencies as DependencyMapType;
|
|
38
|
-
middleware.computedDependencies = await this.extractDependencies(
|
|
44
|
+
middleware.computedDependencies = await this.extractDependencies(
|
|
45
|
+
deps,
|
|
46
|
+
middleware.middleware.id
|
|
47
|
+
);
|
|
39
48
|
}
|
|
40
49
|
|
|
41
50
|
for (const task of this.store.tasks.values()) {
|
|
42
|
-
|
|
43
|
-
task.computedDependencies = await this.extractDependencies(deps);
|
|
44
|
-
|
|
45
|
-
let eventDefinition = task.task.on;
|
|
46
|
-
if (eventDefinition) {
|
|
47
|
-
if (this.store.events.get(eventDefinition.id) === undefined) {
|
|
48
|
-
throw Errors.eventNotFound(eventDefinition.id);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
this.eventManager.addListener(
|
|
52
|
-
eventDefinition,
|
|
53
|
-
async (receivedEvent) => {
|
|
54
|
-
return this.taskRunner.run(
|
|
55
|
-
task.task,
|
|
56
|
-
receivedEvent,
|
|
57
|
-
task.computedDependencies
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
);
|
|
61
|
-
}
|
|
51
|
+
await this.computeTaskDependencies(task);
|
|
62
52
|
}
|
|
63
53
|
|
|
64
54
|
for (const resource of this.store.resources.values()) {
|
|
65
55
|
await this.processResourceDependencies(resource);
|
|
66
56
|
}
|
|
57
|
+
|
|
58
|
+
// leftovers that were registered but not depended upon, except root
|
|
59
|
+
// they should still be initialized as they might extend other
|
|
60
|
+
await this.initializeUninitializedResources();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private async computeTaskDependencies(
|
|
64
|
+
task: TaskStoreElementType<any, any, any>
|
|
65
|
+
) {
|
|
66
|
+
const deps = task.task.dependencies as DependencyMapType;
|
|
67
|
+
task.computedDependencies = await this.extractDependencies(
|
|
68
|
+
deps,
|
|
69
|
+
task.task.id
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
let eventDefinition = task.task.on;
|
|
73
|
+
if (eventDefinition) {
|
|
74
|
+
if (this.store.events.get(eventDefinition.id) === undefined) {
|
|
75
|
+
throw Errors.eventNotFound(eventDefinition.id);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this.eventManager.addListener(
|
|
79
|
+
eventDefinition,
|
|
80
|
+
async (receivedEvent) => {
|
|
81
|
+
this.logger.debug({
|
|
82
|
+
message: `Task ${task.task.id} listened to event: ${eventDefinition.id}`,
|
|
83
|
+
event: receivedEvent,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return this.taskRunner.run(
|
|
87
|
+
task.task,
|
|
88
|
+
receivedEvent,
|
|
89
|
+
task.computedDependencies
|
|
90
|
+
);
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
order: task.task.listenerOrder || 0,
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
}
|
|
67
97
|
}
|
|
68
98
|
|
|
69
99
|
// Most likely these are resources that no-one has dependencies towards
|
|
@@ -93,7 +123,10 @@ export class DependencyProcessor {
|
|
|
93
123
|
resource: ResourceStoreElementType<any, any, {}>
|
|
94
124
|
) {
|
|
95
125
|
const deps = resource.resource.dependencies as DependencyMapType;
|
|
96
|
-
resource.computedDependencies = await this.extractDependencies(
|
|
126
|
+
resource.computedDependencies = await this.extractDependencies(
|
|
127
|
+
deps,
|
|
128
|
+
resource.resource.id
|
|
129
|
+
);
|
|
97
130
|
}
|
|
98
131
|
|
|
99
132
|
public async initializeRoot() {
|
|
@@ -111,10 +144,8 @@ export class DependencyProcessor {
|
|
|
111
144
|
|
|
112
145
|
/**
|
|
113
146
|
* Processes all hooks, should run before emission of any event.
|
|
114
|
-
* @returns
|
|
115
147
|
*/
|
|
116
148
|
public attachHooks() {
|
|
117
|
-
// iterate through resources and send them to processHooks
|
|
118
149
|
for (const resource of this.store.resources.values()) {
|
|
119
150
|
if (resource.resource.hooks) {
|
|
120
151
|
this.attachHooksToResource(resource);
|
|
@@ -141,46 +172,59 @@ export class DependencyProcessor {
|
|
|
141
172
|
|
|
142
173
|
for (const hook of hooks) {
|
|
143
174
|
const event = hook.event;
|
|
175
|
+
const order = hook.order || 0;
|
|
144
176
|
if (event === "*") {
|
|
145
|
-
this.eventManager.addGlobalListener(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
177
|
+
this.eventManager.addGlobalListener(
|
|
178
|
+
async (receivedEvent) => {
|
|
179
|
+
return hook.run(
|
|
180
|
+
receivedEvent,
|
|
181
|
+
resourceStoreElement.computedDependencies as DependencyValuesType<{}>
|
|
182
|
+
);
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
order,
|
|
186
|
+
}
|
|
187
|
+
);
|
|
151
188
|
} else {
|
|
152
189
|
if (this.store.events.has(event.id) === false) {
|
|
153
190
|
throw Errors.eventNotFound(event.id);
|
|
154
191
|
}
|
|
155
|
-
this.eventManager.addListener(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
192
|
+
this.eventManager.addListener(
|
|
193
|
+
event,
|
|
194
|
+
async (receivedEvent) => {
|
|
195
|
+
return hook.run(
|
|
196
|
+
receivedEvent,
|
|
197
|
+
resourceStoreElement.computedDependencies as DependencyValuesType<{}>
|
|
198
|
+
);
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
order,
|
|
202
|
+
}
|
|
203
|
+
);
|
|
161
204
|
}
|
|
162
205
|
}
|
|
163
206
|
}
|
|
164
207
|
|
|
165
208
|
async extractDependencies<T extends DependencyMapType>(
|
|
166
|
-
map: T
|
|
209
|
+
map: T,
|
|
210
|
+
source: string
|
|
167
211
|
): Promise<DependencyValuesType<T>> {
|
|
168
212
|
const object = {} as DependencyValuesType<T>;
|
|
169
213
|
|
|
170
214
|
for (const key in map) {
|
|
171
|
-
object[key] = await this.extractDependency(map[key]);
|
|
215
|
+
object[key] = await this.extractDependency(map[key], source);
|
|
172
216
|
}
|
|
173
217
|
|
|
174
218
|
return object;
|
|
175
219
|
}
|
|
176
220
|
|
|
177
|
-
async extractDependency(object) {
|
|
221
|
+
async extractDependency(object, source: string) {
|
|
178
222
|
if (utils.isResource(object)) {
|
|
179
223
|
return this.extractResourceDependency(object);
|
|
180
224
|
} else if (utils.isTask(object)) {
|
|
181
225
|
return this.extractTaskDependency(object);
|
|
182
226
|
} else if (utils.isEvent(object)) {
|
|
183
|
-
return this.extractEventDependency(object);
|
|
227
|
+
return this.extractEventDependency(object, source);
|
|
184
228
|
} else {
|
|
185
229
|
throw Errors.unknownItemType(object);
|
|
186
230
|
}
|
|
@@ -191,9 +235,17 @@ export class DependencyProcessor {
|
|
|
191
235
|
* @param object
|
|
192
236
|
* @returns
|
|
193
237
|
*/
|
|
194
|
-
extractEventDependency(
|
|
238
|
+
extractEventDependency(
|
|
239
|
+
object: IEventDefinition<Record<string, any>>,
|
|
240
|
+
source: string
|
|
241
|
+
) {
|
|
195
242
|
return async (input) => {
|
|
196
|
-
|
|
243
|
+
// runs it in background.
|
|
244
|
+
this.logger.debug({
|
|
245
|
+
message: `Event ${object.id} was emitted from ${source}`,
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
return this.eventManager.emit(object, input, source);
|
|
197
249
|
};
|
|
198
250
|
}
|
|
199
251
|
|
|
@@ -210,7 +262,8 @@ export class DependencyProcessor {
|
|
|
210
262
|
const dependencies = object.dependencies as DependencyMapType;
|
|
211
263
|
|
|
212
264
|
storeTask.computedDependencies = await this.extractDependencies(
|
|
213
|
-
dependencies
|
|
265
|
+
dependencies,
|
|
266
|
+
storeTask.task.id
|
|
214
267
|
);
|
|
215
268
|
}
|
|
216
269
|
|
|
@@ -242,7 +295,10 @@ export class DependencyProcessor {
|
|
|
242
295
|
storeResource.value = await this.resourceInitializer.initializeResource(
|
|
243
296
|
resource,
|
|
244
297
|
config,
|
|
245
|
-
await this.extractDependencies(
|
|
298
|
+
await this.extractDependencies(
|
|
299
|
+
resource.dependencies || {},
|
|
300
|
+
resource.id
|
|
301
|
+
)
|
|
246
302
|
);
|
|
247
303
|
}
|
|
248
304
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { EventHandlerType, IEvent, IEventDefinition } from "../defs";
|
|
2
2
|
import { Errors } from "../errors";
|
|
3
|
+
import { Logger } from "./Logger";
|
|
3
4
|
|
|
4
5
|
const HandlerOptionsDefaults = { order: 0 };
|
|
5
6
|
|
|
@@ -54,9 +55,9 @@ export class EventManager {
|
|
|
54
55
|
|
|
55
56
|
async emit<TInput>(
|
|
56
57
|
eventDefinition: IEventDefinition<TInput>,
|
|
57
|
-
|
|
58
|
+
data: TInput,
|
|
59
|
+
source: string
|
|
58
60
|
): Promise<void> {
|
|
59
|
-
const data = args[0];
|
|
60
61
|
const eventListeners = this.listeners.get(eventDefinition.id) || [];
|
|
61
62
|
const allListeners = this.mergeSortedListeners(
|
|
62
63
|
eventListeners,
|
|
@@ -67,6 +68,7 @@ export class EventManager {
|
|
|
67
68
|
id: eventDefinition.id,
|
|
68
69
|
data,
|
|
69
70
|
timestamp: new Date(),
|
|
71
|
+
source,
|
|
70
72
|
};
|
|
71
73
|
|
|
72
74
|
for (const listener of allListeners) {
|
package/src/models/Logger.ts
CHANGED
|
@@ -11,13 +11,13 @@ export type LogLevels =
|
|
|
11
11
|
|
|
12
12
|
export interface ILog {
|
|
13
13
|
level: string;
|
|
14
|
-
|
|
14
|
+
source?: string;
|
|
15
15
|
data: any;
|
|
16
16
|
timestamp: Date;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export class Logger {
|
|
20
|
-
|
|
20
|
+
printThreshold: LogLevels | null = null;
|
|
21
21
|
|
|
22
22
|
public severity = {
|
|
23
23
|
trace: 0,
|
|
@@ -28,25 +28,45 @@ export class Logger {
|
|
|
28
28
|
critical: 5,
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
constructor(
|
|
31
|
+
constructor(protected eventManager: EventManager) {}
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* @param level
|
|
35
35
|
* @param message
|
|
36
36
|
*/
|
|
37
|
-
public async log(
|
|
37
|
+
public async log(
|
|
38
|
+
level: LogLevels,
|
|
39
|
+
data: any,
|
|
40
|
+
source?: string
|
|
41
|
+
): Promise<void> {
|
|
38
42
|
const log: ILog = {
|
|
39
43
|
level,
|
|
40
44
|
data,
|
|
45
|
+
source: source,
|
|
41
46
|
timestamp: new Date(),
|
|
42
47
|
};
|
|
43
48
|
|
|
44
|
-
|
|
49
|
+
if (
|
|
50
|
+
this.printThreshold &&
|
|
51
|
+
this.severity[level] >= this.severity[this.printThreshold]
|
|
52
|
+
) {
|
|
53
|
+
this.print(log);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
await this.eventManager.emit(globalEvents.log, log, source || "unknown");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Will print logs after that, use `null` to disable autoprinting.
|
|
61
|
+
* @param level
|
|
62
|
+
*/
|
|
63
|
+
public setPrintThreshold(level: LogLevels | null) {
|
|
64
|
+
this.printThreshold = level;
|
|
45
65
|
}
|
|
46
66
|
|
|
47
|
-
public
|
|
67
|
+
public print(log: ILog) {
|
|
48
68
|
// Extract the relevant information from the log
|
|
49
|
-
const { level, context, data, timestamp } = log;
|
|
69
|
+
const { level, source: context, data, timestamp } = log;
|
|
50
70
|
|
|
51
71
|
// Format the timestamp to a more readable format
|
|
52
72
|
const formattedTimestamp = timestamp.toISOString();
|
|
@@ -74,27 +94,27 @@ export class Logger {
|
|
|
74
94
|
console.log(logMessage);
|
|
75
95
|
}
|
|
76
96
|
|
|
77
|
-
public async info(data: any) {
|
|
78
|
-
await this.log("info", data);
|
|
97
|
+
public async info(data: any, source?: string) {
|
|
98
|
+
await this.log("info", data, source);
|
|
79
99
|
}
|
|
80
100
|
|
|
81
|
-
public async error(data: any) {
|
|
82
|
-
await this.log("error", data);
|
|
101
|
+
public async error(data: any, source?: string) {
|
|
102
|
+
await this.log("error", data, source);
|
|
83
103
|
}
|
|
84
104
|
|
|
85
|
-
public async warn(data: any) {
|
|
86
|
-
await this.log("warn", data);
|
|
105
|
+
public async warn(data: any, source?: string) {
|
|
106
|
+
await this.log("warn", data, source);
|
|
87
107
|
}
|
|
88
108
|
|
|
89
|
-
public async debug(data: any) {
|
|
90
|
-
await this.log("debug", data);
|
|
109
|
+
public async debug(data: any, source?: string) {
|
|
110
|
+
await this.log("debug", data, source);
|
|
91
111
|
}
|
|
92
112
|
|
|
93
|
-
public async trace(data: any) {
|
|
94
|
-
await this.log("trace", data);
|
|
113
|
+
public async trace(data: any, source?: string) {
|
|
114
|
+
await this.log("trace", data, source);
|
|
95
115
|
}
|
|
96
116
|
|
|
97
|
-
public async critical(data: any) {
|
|
98
|
-
await this.log("critical", data);
|
|
117
|
+
public async critical(data: any, source?: string) {
|
|
118
|
+
await this.log("critical", data, source);
|
|
99
119
|
}
|
|
100
120
|
}
|
|
@@ -7,11 +7,13 @@ import {
|
|
|
7
7
|
import { EventManager } from "./EventManager";
|
|
8
8
|
import { globalEvents } from "../globalEvents";
|
|
9
9
|
import { MiddlewareStoreElementType, Store } from "./Store";
|
|
10
|
+
import { Logger } from "./Logger";
|
|
10
11
|
|
|
11
12
|
export class ResourceInitializer {
|
|
12
13
|
constructor(
|
|
13
14
|
protected readonly store: Store,
|
|
14
|
-
protected readonly eventManager: EventManager
|
|
15
|
+
protected readonly eventManager: EventManager,
|
|
16
|
+
protected readonly logger: Logger
|
|
15
17
|
) {}
|
|
16
18
|
|
|
17
19
|
/**
|
|
@@ -27,14 +29,20 @@ export class ResourceInitializer {
|
|
|
27
29
|
config: TConfig,
|
|
28
30
|
dependencies: DependencyValuesType<TDeps>
|
|
29
31
|
): Promise<TValue | undefined> {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
await this.eventManager.emit(
|
|
33
|
+
globalEvents.resources.beforeInit,
|
|
34
|
+
{
|
|
35
|
+
config,
|
|
36
|
+
resource,
|
|
37
|
+
},
|
|
38
|
+
resource.id
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
await this.eventManager.emit(
|
|
42
|
+
resource.events.beforeInit,
|
|
43
|
+
{ config },
|
|
44
|
+
resource.id
|
|
45
|
+
);
|
|
38
46
|
|
|
39
47
|
let error, value;
|
|
40
48
|
try {
|
|
@@ -42,15 +50,25 @@ export class ResourceInitializer {
|
|
|
42
50
|
value = await this.initWithMiddleware(resource, config, dependencies);
|
|
43
51
|
}
|
|
44
52
|
|
|
45
|
-
await this.eventManager.emit(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
resource
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
await this.eventManager.emit(
|
|
54
|
+
resource.events.afterInit,
|
|
55
|
+
{
|
|
56
|
+
config,
|
|
57
|
+
value,
|
|
58
|
+
},
|
|
59
|
+
resource.id
|
|
60
|
+
);
|
|
61
|
+
await this.eventManager.emit(
|
|
62
|
+
globalEvents.resources.afterInit,
|
|
63
|
+
{
|
|
64
|
+
config,
|
|
65
|
+
resource,
|
|
66
|
+
value,
|
|
67
|
+
},
|
|
68
|
+
resource.id
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
this.logger.debug(`Resource ${resource.id} initialized`);
|
|
54
72
|
|
|
55
73
|
return value;
|
|
56
74
|
} catch (e) {
|
|
@@ -59,15 +77,23 @@ export class ResourceInitializer {
|
|
|
59
77
|
const suppress = () => (isSuppressed = true);
|
|
60
78
|
|
|
61
79
|
// If you want to rewthrow the error, this should be done inside the onError event.
|
|
62
|
-
await this.eventManager.emit(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
resource
|
|
69
|
-
|
|
70
|
-
|
|
80
|
+
await this.eventManager.emit(
|
|
81
|
+
resource.events.onError,
|
|
82
|
+
{
|
|
83
|
+
error,
|
|
84
|
+
suppress,
|
|
85
|
+
},
|
|
86
|
+
resource.id
|
|
87
|
+
);
|
|
88
|
+
await this.eventManager.emit(
|
|
89
|
+
globalEvents.resources.onError,
|
|
90
|
+
{
|
|
91
|
+
error,
|
|
92
|
+
resource,
|
|
93
|
+
suppress,
|
|
94
|
+
},
|
|
95
|
+
resource.id
|
|
96
|
+
);
|
|
71
97
|
|
|
72
98
|
if (!isSuppressed) throw e;
|
|
73
99
|
}
|
package/src/models/Store.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { Errors } from "../errors";
|
|
|
17
17
|
import { globalResources } from "../globalResources";
|
|
18
18
|
import { EventManager } from "./EventManager";
|
|
19
19
|
import { TaskRunner } from "./TaskRunner";
|
|
20
|
+
import { Logger } from "./Logger";
|
|
20
21
|
|
|
21
22
|
export type ResourceStoreElementType<
|
|
22
23
|
C = any,
|
|
@@ -67,7 +68,10 @@ export class Store {
|
|
|
67
68
|
#isLocked = false;
|
|
68
69
|
#isInitialized = false;
|
|
69
70
|
|
|
70
|
-
constructor(
|
|
71
|
+
constructor(
|
|
72
|
+
protected readonly eventManager: EventManager,
|
|
73
|
+
protected readonly logger: Logger
|
|
74
|
+
) {}
|
|
71
75
|
|
|
72
76
|
get isLocked() {
|
|
73
77
|
return this.#isLocked;
|
|
@@ -378,12 +382,22 @@ export class Store {
|
|
|
378
382
|
});
|
|
379
383
|
}
|
|
380
384
|
|
|
385
|
+
private middlewareAsMap(middleware: IMiddlewareDefinition[]) {
|
|
386
|
+
return middleware.reduce((acc, item) => {
|
|
387
|
+
acc[item.id] = item;
|
|
388
|
+
return acc;
|
|
389
|
+
}, {} as Record<string, IMiddlewareDefinition>);
|
|
390
|
+
}
|
|
391
|
+
|
|
381
392
|
getDependentNodes(): IDependentNode[] {
|
|
382
393
|
const depenedants: IDependentNode[] = [];
|
|
383
394
|
for (const task of this.tasks.values()) {
|
|
384
395
|
depenedants.push({
|
|
385
396
|
id: task.task.id,
|
|
386
|
-
dependencies:
|
|
397
|
+
dependencies: {
|
|
398
|
+
...task.task.dependencies,
|
|
399
|
+
...this.middlewareAsMap(task.task.middleware),
|
|
400
|
+
},
|
|
387
401
|
});
|
|
388
402
|
}
|
|
389
403
|
for (const middleware of this.middlewares.values()) {
|
|
@@ -395,7 +409,10 @@ export class Store {
|
|
|
395
409
|
for (const resource of this.resources.values()) {
|
|
396
410
|
depenedants.push({
|
|
397
411
|
id: resource.resource.id,
|
|
398
|
-
dependencies:
|
|
412
|
+
dependencies: {
|
|
413
|
+
...resource.resource.dependencies,
|
|
414
|
+
...this.middlewareAsMap(resource.resource.middleware),
|
|
415
|
+
},
|
|
399
416
|
});
|
|
400
417
|
}
|
|
401
418
|
|
package/src/models/TaskRunner.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
Store,
|
|
8
8
|
TaskStoreElementType,
|
|
9
9
|
} from "./Store";
|
|
10
|
+
import { Logger } from "./Logger";
|
|
10
11
|
|
|
11
12
|
export class TaskRunner {
|
|
12
13
|
protected readonly runnerStore = new Map<
|
|
@@ -16,7 +17,8 @@ export class TaskRunner {
|
|
|
16
17
|
|
|
17
18
|
constructor(
|
|
18
19
|
protected readonly store: Store,
|
|
19
|
-
protected readonly eventManager: EventManager
|
|
20
|
+
protected readonly eventManager: EventManager,
|
|
21
|
+
protected readonly logger: Logger
|
|
20
22
|
) {}
|
|
21
23
|
|
|
22
24
|
/**
|
|
@@ -51,23 +53,35 @@ export class TaskRunner {
|
|
|
51
53
|
// begin by dispatching the event of creating it.
|
|
52
54
|
// then ensure the hooks are called
|
|
53
55
|
// then ensure the middleware are called
|
|
54
|
-
await this.eventManager.emit(task.events.beforeRun, { input });
|
|
55
|
-
await this.eventManager.emit(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
await this.eventManager.emit(task.events.beforeRun, { input }, task.id);
|
|
57
|
+
await this.eventManager.emit(
|
|
58
|
+
globalEvents.tasks.beforeRun,
|
|
59
|
+
{
|
|
60
|
+
task,
|
|
61
|
+
input,
|
|
62
|
+
},
|
|
63
|
+
task.id
|
|
64
|
+
);
|
|
59
65
|
|
|
60
66
|
let error;
|
|
61
67
|
try {
|
|
62
68
|
// craft the next function starting from the first next function
|
|
63
69
|
const output = await runner(input);
|
|
64
70
|
|
|
65
|
-
await this.eventManager.emit(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
await this.eventManager.emit(
|
|
72
|
+
task.events.afterRun,
|
|
73
|
+
{ input, output },
|
|
74
|
+
task.id
|
|
75
|
+
);
|
|
76
|
+
await this.eventManager.emit(
|
|
77
|
+
globalEvents.tasks.afterRun,
|
|
78
|
+
{
|
|
79
|
+
task,
|
|
80
|
+
input,
|
|
81
|
+
output,
|
|
82
|
+
},
|
|
83
|
+
task.id
|
|
84
|
+
);
|
|
71
85
|
|
|
72
86
|
return output;
|
|
73
87
|
} catch (e) {
|
|
@@ -76,12 +90,20 @@ export class TaskRunner {
|
|
|
76
90
|
error = e;
|
|
77
91
|
|
|
78
92
|
// If you want to rewthrow the error, this should be done inside the onError event.
|
|
79
|
-
await this.eventManager.emit(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
93
|
+
await this.eventManager.emit(
|
|
94
|
+
task.events.onError,
|
|
95
|
+
{ error, suppress },
|
|
96
|
+
task.id
|
|
97
|
+
);
|
|
98
|
+
await this.eventManager.emit(
|
|
99
|
+
globalEvents.tasks.onError,
|
|
100
|
+
{
|
|
101
|
+
task,
|
|
102
|
+
error,
|
|
103
|
+
suppress,
|
|
104
|
+
},
|
|
105
|
+
task.id
|
|
106
|
+
);
|
|
85
107
|
|
|
86
108
|
if (!isSuppressed) throw e;
|
|
87
109
|
}
|
|
@@ -104,6 +126,11 @@ export class TaskRunner {
|
|
|
104
126
|
) {
|
|
105
127
|
// this is the final next()
|
|
106
128
|
let next = async (input) => {
|
|
129
|
+
this.logger.debug({
|
|
130
|
+
message: `Running task ${task.id}`,
|
|
131
|
+
input,
|
|
132
|
+
});
|
|
133
|
+
|
|
107
134
|
return task.run.call(null, input, taskDependencies as any);
|
|
108
135
|
};
|
|
109
136
|
|