@adaas/a-utils 0.1.24 → 0.1.26
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/dist/index.cjs +13 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +34 -1
- package/dist/index.d.ts +34 -1
- package/dist/index.mjs +13 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +7 -0
- package/src/lib/A-Service/A-Service.constants.ts +17 -0
- package/src/lib/A-Service/A-Service.container.ts +162 -0
- package/src/lib/A-Service/A-Service.error.ts +11 -0
- package/src/lib/A-Service/A-Service.types.ts +32 -0
- package/tests/A-Command.test.ts +65 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adaas/a-utils",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.26",
|
|
4
4
|
"description": "A-Utils is a set of utilities that are used across the ADAAS ecosystem. This package is designed to be a collection of utilities that are used across the ADAAS ecosystem.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"build": "tsup --config tsup.config.ts"
|
|
81
81
|
},
|
|
82
82
|
"dependencies": {
|
|
83
|
-
"@adaas/a-concept": "^0.1.
|
|
83
|
+
"@adaas/a-concept": "^0.1.47"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"@types/chai": "^4.3.14",
|
package/src/index.ts
CHANGED
|
@@ -71,6 +71,13 @@ export { A_ExecutionContext } from './lib/A-Execution/A-Execution.context';
|
|
|
71
71
|
export { A_OperationContext } from './lib/A-Operation/A-Operation.context';
|
|
72
72
|
export * from './lib/A-Operation/A-Operation.types';
|
|
73
73
|
|
|
74
|
+
// ============================================================================
|
|
75
|
+
// A-Service Container
|
|
76
|
+
// ============================================================================
|
|
77
|
+
export { A_Service } from './lib/A-Service/A-Service.container';
|
|
78
|
+
// export * from './lib/A-Service/A-Service.types';
|
|
79
|
+
export * from './lib/A-Service/A-Service.constants';
|
|
80
|
+
|
|
74
81
|
// ============================================================================
|
|
75
82
|
// A-Polyfill Components
|
|
76
83
|
// ============================================================================
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export enum A_ServiceFeatures {
|
|
2
|
+
|
|
3
|
+
onBeforeLoad = '_A_Service_onBeforeLoad',
|
|
4
|
+
onLoad = '_A_Service_onLoad',
|
|
5
|
+
onAfterLoad = '_A_Service_onAfterLoad',
|
|
6
|
+
|
|
7
|
+
onBeforeStart = '_A_Service_onBeforeStart',
|
|
8
|
+
onStart = '_A_Service_onStart',
|
|
9
|
+
onAfterStart = '_A_Service_onAfterStart',
|
|
10
|
+
|
|
11
|
+
onBeforeStop = '_A_Service_onBeforeStop',
|
|
12
|
+
onStop = '_A_Service_onStop',
|
|
13
|
+
onAfterStop = '_A_Service_onAfterStop',
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
onError = '_A_Service_onError',
|
|
17
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { A_Concept, A_Container, A_Error, A_Feature, A_Inject } from "@adaas/a-concept";
|
|
2
|
+
import { A_ServiceFeatures } from "./A-Service.constants";
|
|
3
|
+
import { A_Polyfill } from "../A-Polyfill/A-Polyfill.component";
|
|
4
|
+
import { A_Config } from "../A-Config/A-Config.context";
|
|
5
|
+
import { A_Logger } from "../A-Logger/A-Logger.component";
|
|
6
|
+
import { A_Service_Error } from "./A-Service.error";
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A-Service is a container that can run different types of services, such as HTTP servers, workers, etc.
|
|
13
|
+
* Depending on the provided config and configuration, it will load the necessary components and start the service.
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
export class A_Service extends A_Container {
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@A_Concept.Start()
|
|
20
|
+
/**
|
|
21
|
+
* Start the server
|
|
22
|
+
*/
|
|
23
|
+
async start() {
|
|
24
|
+
try {
|
|
25
|
+
await this.call(A_ServiceFeatures.onBeforeStart);
|
|
26
|
+
|
|
27
|
+
await this.call(A_ServiceFeatures.onStart);
|
|
28
|
+
|
|
29
|
+
await this.call(A_ServiceFeatures.onAfterStart);
|
|
30
|
+
|
|
31
|
+
} catch (error) {
|
|
32
|
+
|
|
33
|
+
let wrappedError;
|
|
34
|
+
|
|
35
|
+
switch (true) {
|
|
36
|
+
case error instanceof A_Service_Error:
|
|
37
|
+
wrappedError = error;
|
|
38
|
+
break;
|
|
39
|
+
|
|
40
|
+
case error instanceof A_Error && error.originalError instanceof A_Service_Error:
|
|
41
|
+
wrappedError = error.originalError;
|
|
42
|
+
break;
|
|
43
|
+
|
|
44
|
+
default:
|
|
45
|
+
wrappedError = new A_Service_Error({
|
|
46
|
+
title: A_Service_Error.ServiceStartError,
|
|
47
|
+
description: 'An error occurred while processing the request.',
|
|
48
|
+
originalError: error
|
|
49
|
+
})
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this.scope.register(wrappedError);
|
|
54
|
+
|
|
55
|
+
await this.call(A_ServiceFeatures.onError);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@A_Concept.Stop()
|
|
61
|
+
/**
|
|
62
|
+
* Stop the server
|
|
63
|
+
*/
|
|
64
|
+
async stop() {
|
|
65
|
+
try {
|
|
66
|
+
await this.call(A_ServiceFeatures.onBeforeStop);
|
|
67
|
+
|
|
68
|
+
await this.call(A_ServiceFeatures.onStop);
|
|
69
|
+
|
|
70
|
+
await this.call(A_ServiceFeatures.onAfterStop);
|
|
71
|
+
|
|
72
|
+
} catch (error) {
|
|
73
|
+
|
|
74
|
+
let wrappedError;
|
|
75
|
+
|
|
76
|
+
switch (true) {
|
|
77
|
+
case error instanceof A_Service_Error:
|
|
78
|
+
wrappedError = error;
|
|
79
|
+
break;
|
|
80
|
+
|
|
81
|
+
case error instanceof A_Error && error.originalError instanceof A_Service_Error:
|
|
82
|
+
wrappedError = error.originalError;
|
|
83
|
+
break;
|
|
84
|
+
|
|
85
|
+
default:
|
|
86
|
+
wrappedError = new A_Service_Error({
|
|
87
|
+
title: A_Service_Error.ServiceStopError,
|
|
88
|
+
description: 'An error occurred while processing the request.',
|
|
89
|
+
originalError: error
|
|
90
|
+
})
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
this.scope.register(wrappedError);
|
|
95
|
+
|
|
96
|
+
await this.call(A_ServiceFeatures.onError);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ======================================================================================
|
|
101
|
+
// ============================= A-Service Lifecycle =================================
|
|
102
|
+
// ======================================================================================
|
|
103
|
+
|
|
104
|
+
@A_Feature.Extend()
|
|
105
|
+
protected async [A_ServiceFeatures.onBeforeLoad](
|
|
106
|
+
@A_Inject(A_Polyfill) polyfill: A_Polyfill,
|
|
107
|
+
): Promise<void> {
|
|
108
|
+
// Initialize Polyfill
|
|
109
|
+
if (!polyfill) {
|
|
110
|
+
this.scope.register(A_Polyfill);
|
|
111
|
+
polyfill = this.scope.resolve(A_Polyfill)!
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@A_Feature.Extend()
|
|
116
|
+
protected async [A_ServiceFeatures.onLoad](...args: any[]) { }
|
|
117
|
+
|
|
118
|
+
@A_Feature.Extend()
|
|
119
|
+
protected async [A_ServiceFeatures.onAfterLoad](...args: any[]) { }
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@A_Feature.Extend()
|
|
123
|
+
protected async [A_ServiceFeatures.onBeforeStart](...args: any[]) { }
|
|
124
|
+
|
|
125
|
+
@A_Feature.Extend()
|
|
126
|
+
protected async [A_ServiceFeatures.onStart](...args: any[]) { }
|
|
127
|
+
|
|
128
|
+
@A_Feature.Extend()
|
|
129
|
+
protected async [A_ServiceFeatures.onAfterStart](...args: any[]) { }
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@A_Feature.Extend()
|
|
134
|
+
protected async [A_ServiceFeatures.onBeforeStop](...args: any[]) { }
|
|
135
|
+
|
|
136
|
+
@A_Feature.Extend()
|
|
137
|
+
protected async [A_ServiceFeatures.onStop](...args: any[]) { }
|
|
138
|
+
|
|
139
|
+
@A_Feature.Extend()
|
|
140
|
+
protected async [A_ServiceFeatures.onAfterStop](...args: any[]) { }
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@A_Feature.Extend({
|
|
145
|
+
before: /.*/
|
|
146
|
+
})
|
|
147
|
+
protected async [A_ServiceFeatures.onError](
|
|
148
|
+
@A_Inject(A_Error) error: A_Error,
|
|
149
|
+
@A_Inject(A_Logger) logger?: A_Logger,
|
|
150
|
+
...args: any[]) {
|
|
151
|
+
logger?.error(error);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { A_Component, A_Fragment } from "@adaas/a-concept";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export type A_SERVER_TYPES__ServerFeatures = [
|
|
5
|
+
A_SERVER_TYPES__ServerFeature.beforeStart,
|
|
6
|
+
A_SERVER_TYPES__ServerFeature.afterStart,
|
|
7
|
+
A_SERVER_TYPES__ServerFeature.beforeStop,
|
|
8
|
+
A_SERVER_TYPES__ServerFeature.afterStop,
|
|
9
|
+
A_SERVER_TYPES__ServerFeature.onRequest
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
export enum A_SERVER_TYPES__ServerFeature {
|
|
13
|
+
beforeStart = 'beforeStart',
|
|
14
|
+
afterStart = 'afterStart',
|
|
15
|
+
beforeStop = 'beforeStop',
|
|
16
|
+
afterStop = 'afterStop',
|
|
17
|
+
beforeRequest = 'beforeRequest',
|
|
18
|
+
onRequest = 'onRequest',
|
|
19
|
+
afterRequest = 'afterRequest',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
export type A_ServiceConstructor = {
|
|
24
|
+
name: string,
|
|
25
|
+
version: string,
|
|
26
|
+
controllers: Array<A_Component>,
|
|
27
|
+
entities: Array<A_Fragment>,
|
|
28
|
+
extensions: Array<A_Component>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
package/tests/A-Command.test.ts
CHANGED
|
@@ -612,6 +612,71 @@ describe('A-Command tests', () => {
|
|
|
612
612
|
expect([A_Command_Status.COMPLETED, A_Command_Status.FAILED])
|
|
613
613
|
.toContain(command.status);
|
|
614
614
|
});
|
|
615
|
+
|
|
616
|
+
it('Should stop command execution in case of error', async () => {
|
|
617
|
+
|
|
618
|
+
class FailingProcessor extends A_Component {
|
|
619
|
+
|
|
620
|
+
@A_Feature.Extend({
|
|
621
|
+
name: A_CommandFeatures.onExecute
|
|
622
|
+
})
|
|
623
|
+
async step1(
|
|
624
|
+
@A_Inject(A_Caller) command: ErrorTestCommand
|
|
625
|
+
) {
|
|
626
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
627
|
+
|
|
628
|
+
testExecutionLog.push('Step 1 executed');
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
@A_Feature.Extend({
|
|
632
|
+
name: A_CommandFeatures.onExecute
|
|
633
|
+
})
|
|
634
|
+
async step2(
|
|
635
|
+
@A_Inject(A_Caller) command: ErrorTestCommand
|
|
636
|
+
) {
|
|
637
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
638
|
+
testExecutionLog.push('Step 2 executed');
|
|
639
|
+
throw new Error('Simulated error in step 2');
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
@A_Feature.Extend({
|
|
643
|
+
name: A_CommandFeatures.onExecute
|
|
644
|
+
})
|
|
645
|
+
async step3(
|
|
646
|
+
@A_Inject(A_Caller) command: ErrorTestCommand
|
|
647
|
+
) {
|
|
648
|
+
testExecutionLog.push('Step 3 executed');
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
const container = new A_Container({
|
|
653
|
+
name: 'Error Stop Test Container',
|
|
654
|
+
components: [
|
|
655
|
+
FailingProcessor,
|
|
656
|
+
A_StateMachine
|
|
657
|
+
],
|
|
658
|
+
entities: [ErrorTestCommand]
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
const concept = new A_Concept({
|
|
662
|
+
containers: [container]
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
await concept.load();
|
|
666
|
+
|
|
667
|
+
const command = new ErrorTestCommand({ shouldFail: true });
|
|
668
|
+
container.scope.register(command);
|
|
669
|
+
|
|
670
|
+
await command.execute();
|
|
671
|
+
|
|
672
|
+
expect(command.status).toBe(A_Command_Status.FAILED);
|
|
673
|
+
expect(command.error).toBeDefined();
|
|
674
|
+
expect(command.isProcessed).toBe(true);
|
|
675
|
+
expect(testExecutionLog).toEqual([
|
|
676
|
+
'Step 1 executed',
|
|
677
|
+
'Step 2 executed'
|
|
678
|
+
]); // Step 3 should not be executed
|
|
679
|
+
});
|
|
615
680
|
});
|
|
616
681
|
|
|
617
682
|
// =============================================================================
|