@adaas/a-concept 0.0.28 → 0.0.30
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/examples/fe-be/channels/Test.channel.d.ts +6 -0
- package/dist/examples/fe-be/channels/Test.channel.js +14 -0
- package/dist/examples/fe-be/channels/Test.channel.js.map +1 -0
- package/dist/examples/fe-be/components/BE-Controller.component.d.ts +4 -0
- package/dist/examples/fe-be/components/BE-Controller.component.js +24 -0
- package/dist/examples/fe-be/components/BE-Controller.component.js.map +1 -0
- package/dist/examples/fe-be/components/FE.component.d.ts +4 -0
- package/dist/examples/fe-be/components/FE.component.js +31 -0
- package/dist/examples/fe-be/components/FE.component.js.map +1 -0
- package/dist/examples/fe-be/components/UserActions.component.d.ts +5 -0
- package/dist/examples/fe-be/components/UserActions.component.js +25 -0
- package/dist/examples/fe-be/components/UserActions.component.js.map +1 -0
- package/dist/examples/fe-be/concept.d.ts +0 -0
- package/dist/examples/fe-be/concept.js +2 -0
- package/dist/examples/fe-be/concept.js.map +1 -0
- package/dist/examples/fe-be/containers/ServerApp.container.d.ts +3 -0
- package/dist/examples/fe-be/containers/ServerApp.container.js +8 -0
- package/dist/examples/fe-be/containers/ServerApp.container.js.map +1 -0
- package/dist/examples/fe-be/containers/WebApp.container.d.ts +3 -0
- package/dist/examples/fe-be/containers/WebApp.container.js +8 -0
- package/dist/examples/fe-be/containers/WebApp.container.js.map +1 -0
- package/dist/examples/multi-container/channels/Direct.channel.d.ts +9 -0
- package/dist/examples/multi-container/channels/Direct.channel.js +32 -0
- package/dist/examples/multi-container/channels/Direct.channel.js.map +1 -0
- package/dist/examples/multi-container/concept.d.ts +0 -0
- package/dist/examples/multi-container/concept.js +2 -0
- package/dist/examples/multi-container/concept.js.map +1 -0
- package/dist/examples/multi-container/containers/Command.container.d.ts +11 -0
- package/dist/examples/multi-container/containers/Command.container.js +51 -0
- package/dist/examples/multi-container/containers/Command.container.js.map +1 -0
- package/dist/examples/multi-container/containers/Schedule.container.d.ts +15 -0
- package/dist/examples/multi-container/containers/Schedule.container.js +67 -0
- package/dist/examples/multi-container/containers/Schedule.container.js.map +1 -0
- package/dist/examples/simple/components/A.component.js.map +1 -1
- package/dist/examples/simple/containers/Main.container.js +7 -3
- package/dist/examples/simple/containers/Main.container.js.map +1 -1
- package/dist/examples/simple/entities/EntityA.entity.d.ts +8 -0
- package/dist/examples/simple/entities/EntityA.entity.js +22 -0
- package/dist/examples/simple/entities/EntityA.entity.js.map +1 -0
- package/dist/examples/simple-http-server/contexts/http-request.context.d.ts +0 -1
- package/dist/examples/simple-http-server/contexts/http-request.context.js +6 -8
- package/dist/examples/simple-http-server/contexts/http-request.context.js.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.js +16 -7
- package/dist/index.js.map +1 -1
- package/dist/src/base/A-Config/components/ConfigReader.component.d.ts +2 -1
- package/dist/src/base/A-Config/components/ConfigReader.component.js +12 -12
- package/dist/src/base/A-Config/components/ConfigReader.component.js.map +1 -1
- package/dist/src/decorators/A-Abstraction/A-Abstraction.decorator.d.ts +14 -0
- package/dist/src/decorators/A-Abstraction/A-Abstraction.decorator.js +53 -0
- package/dist/src/decorators/A-Abstraction/A-Abstraction.decorator.js.map +1 -0
- package/dist/src/decorators/A-Abstraction/A-Abstraction.decorator.types.d.ts +2 -0
- package/dist/src/decorators/A-Abstraction/A-Abstraction.decorator.types.js +3 -0
- package/dist/src/decorators/A-Abstraction/A-Abstraction.decorator.types.js.map +1 -0
- package/dist/src/decorators/A-Connect/A-Connect.decorator.d.ts +19 -0
- package/dist/src/decorators/A-Connect/A-Connect.decorator.js +31 -0
- package/dist/src/decorators/A-Connect/A-Connect.decorator.js.map +1 -0
- package/dist/src/decorators/A-Connect/A-Connect.decorator.types.d.ts +1 -0
- package/dist/src/decorators/A-Connect/A-Connect.decorator.types.js +3 -0
- package/dist/src/decorators/A-Connect/A-Connect.decorator.types.js.map +1 -0
- package/dist/src/decorators/A-Entity/A-Entity-List.decorator.d.ts +1 -0
- package/dist/src/decorators/A-Entity/A-Entity-List.decorator.js +8 -0
- package/dist/src/decorators/A-Entity/A-Entity-List.decorator.js.map +1 -0
- package/dist/src/decorators/A-Entity/A-Entity.decorator.types.d.ts +14 -0
- package/dist/src/decorators/A-Entity/A-Entity.decorator.types.js +3 -0
- package/dist/src/decorators/A-Entity/A-Entity.decorator.types.js.map +1 -0
- package/dist/src/decorators/A-Feature/A-Feature-Extend.decorator.js +9 -0
- package/dist/src/decorators/A-Feature/A-Feature-Extend.decorator.js.map +1 -1
- package/dist/src/decorators/A-Feature/A-Feature.decorator.types.d.ts +28 -0
- package/dist/src/decorators/A-Inject/A-Inject.decorator.d.ts +2 -3
- package/dist/src/decorators/A-Inject/A-Inject.decorator.js.map +1 -1
- package/dist/src/decorators/A-Inject/A-Inject.decorator.types.d.ts +44 -0
- package/dist/src/global/A-Channel/A-Channel.class.d.ts +8 -10
- package/dist/src/global/A-Channel/A-Channel.class.js +12 -26
- package/dist/src/global/A-Channel/A-Channel.class.js.map +1 -1
- package/dist/src/global/A-Channel/A-Channel.types.d.ts +32 -0
- package/dist/src/global/A-Component/A-Component.class.d.ts +2 -1
- package/dist/src/global/A-Component/A-Component.class.js +1 -0
- package/dist/src/global/A-Component/A-Component.class.js.map +1 -1
- package/dist/src/global/A-Component/A-Component.meta.d.ts +8 -0
- package/dist/src/global/A-Component/A-Component.meta.js +27 -1
- package/dist/src/global/A-Component/A-Component.meta.js.map +1 -1
- package/dist/src/global/A-Component/A-Component.types.d.ts +19 -34
- package/dist/src/global/A-Component/A-Component.types.js +1 -7
- package/dist/src/global/A-Component/A-Component.types.js.map +1 -1
- package/dist/src/global/A-Concept/A_Concept.class.d.ts +7 -7
- package/dist/src/global/A-Concept/A_Concept.class.js +30 -30
- package/dist/src/global/A-Concept/A_Concept.class.js.map +1 -1
- package/dist/src/global/A-Concept/A_Concept.types.d.ts +42 -2
- package/dist/src/global/A-Concept/A_Concept.types.js.map +1 -1
- package/dist/src/global/A-Container/A-Container.class.d.ts +1 -8
- package/dist/src/global/A-Container/A-Container.class.js +1 -31
- package/dist/src/global/A-Container/A-Container.class.js.map +1 -1
- package/dist/src/global/A-Container/A-Container.meta.d.ts +8 -0
- package/dist/src/global/A-Container/A-Container.meta.js +29 -0
- package/dist/src/global/A-Container/A-Container.meta.js.map +1 -1
- package/dist/src/global/A-Container/A-Container.types.d.ts +23 -7
- package/dist/src/global/A-Container/A-Container.types.js +2 -1
- package/dist/src/global/A-Container/A-Container.types.js.map +1 -1
- package/dist/src/global/A-Context/A-Context.class.js +6 -35
- package/dist/src/global/A-Context/A-Context.class.js.map +1 -1
- package/dist/src/global/A-Entity/A-Entity.class.d.ts +1 -2
- package/dist/src/global/A-Entity/A-Entity.class.js +6 -7
- package/dist/src/global/A-Entity/A-Entity.class.js.map +1 -1
- package/dist/src/global/A-Entity/A-Entity.types.d.ts +4 -5
- package/dist/src/global/A-Entity/A-Entity.types.js.map +1 -1
- package/dist/src/global/A-Feature/A-Feature.class.d.ts +30 -6
- package/dist/src/global/A-Feature/A-Feature.class.js +49 -40
- package/dist/src/global/A-Feature/A-Feature.class.js.map +1 -1
- package/dist/src/global/A-Feature/A-Feature.types.d.ts +2 -24
- package/dist/src/global/A-Feature/A-Feature.types.js +21 -0
- package/dist/src/global/A-Feature/A-Feature.types.js.map +1 -1
- package/dist/src/global/A-Fragment/A-Fragment.class.d.ts +8 -0
- package/dist/src/global/A-Fragment/A-Fragment.class.js +10 -0
- package/dist/src/global/A-Fragment/A-Fragment.class.js.map +1 -1
- package/dist/src/global/A-Scope/A-Scope.class.d.ts +7 -5
- package/dist/src/global/A-Scope/A-Scope.class.js +33 -10
- package/dist/src/global/A-Scope/A-Scope.class.js.map +1 -1
- package/dist/src/global/A-Scope/A-Scope.types.d.ts +2 -1
- package/dist/src/global/A-Stage/A-Stage.class.d.ts +69 -0
- package/dist/src/global/A-Stage/A-Stage.class.js +176 -0
- package/dist/src/global/A-Stage/A-Stage.class.js.map +1 -0
- package/dist/src/global/A-Stage/A-Stage.types.d.ts +83 -0
- package/dist/src/global/A-Stage/A-Stage.types.js +59 -0
- package/dist/src/global/A-Stage/A-Stage.types.js.map +1 -0
- package/dist/src/helpers/StepsManager.class.d.ts +15 -0
- package/dist/src/helpers/StepsManager.class.js +85 -0
- package/dist/src/helpers/StepsManager.class.js.map +1 -0
- package/examples/fe-be/channels/Test.channel.ts +24 -0
- package/examples/fe-be/components/BE-Controller.component.ts +20 -0
- package/examples/fe-be/components/FE.component.ts +13 -0
- package/examples/fe-be/concept.ts +0 -0
- package/examples/fe-be/containers/ServerApp.container.ts +8 -0
- package/examples/fe-be/containers/WebApp.container.ts +13 -0
- package/examples/multi-container/channels/Direct.channel.ts +39 -0
- package/examples/multi-container/concept.ts +0 -0
- package/examples/multi-container/containers/Command.container.ts +41 -0
- package/examples/multi-container/containers/Schedule.container.ts +57 -0
- package/examples/simple/components/A.component.ts +2 -1
- package/examples/simple/containers/Main.container.ts +11 -3
- package/examples/simple/entities/EntityA.entity.ts +16 -0
- package/examples/simple-http-server/contexts/http-request.context.ts +6 -6
- package/index.ts +12 -3
- package/package.json +1 -1
- package/src/base/A-Config/components/ConfigReader.component.ts +12 -11
- package/src/decorators/A-Abstraction/A-Abstraction.decorator.ts +82 -0
- package/src/decorators/{A-Stage/A-Stage.decorator.types.ts → A-Abstraction/A-Abstraction.decorator.types.ts} +1 -3
- package/src/decorators/A-Connect/A-Connect.decorator.ts +71 -0
- package/src/decorators/A-Connect/A-Connect.decorator.types.ts +6 -0
- package/src/decorators/A-Entity/A-Entity-List.decorator.ts +12 -0
- package/src/decorators/A-Entity/A-Entity.decorator.types.ts +18 -0
- package/src/decorators/A-Feature/A-Feature-Extend.decorator.ts +10 -0
- package/src/decorators/A-Feature/A-Feature.decorator.types.ts +36 -0
- package/src/decorators/A-Inject/A-Inject.decorator.ts +7 -7
- package/src/decorators/A-Inject/A-Inject.decorator.types.ts +47 -1
- package/src/global/A-Channel/A-Channel.class.ts +25 -28
- package/src/global/A-Channel/A-Channel.types.ts +53 -0
- package/src/global/A-Component/A-Component.class.ts +10 -2
- package/src/global/A-Component/A-Component.meta.ts +42 -1
- package/src/global/A-Component/A-Component.types.ts +20 -40
- package/src/global/A-Concept/A_Concept.class.ts +52 -31
- package/src/global/A-Concept/A_Concept.types.ts +48 -3
- package/src/global/A-Container/A-Container.class.ts +3 -39
- package/src/global/A-Container/A-Container.meta.ts +41 -4
- package/src/global/A-Container/A-Container.types.ts +28 -7
- package/src/global/A-Context/A-Context.class.ts +9 -49
- package/src/global/A-Entity/A-Entity.class.ts +8 -6
- package/src/global/A-Entity/A-Entity.types.ts +4 -5
- package/src/global/A-Feature/A-Feature.class.ts +73 -61
- package/src/global/A-Feature/A-Feature.types.ts +24 -23
- package/src/global/A-Fragment/A-Fragment.class.ts +15 -0
- package/src/global/A-Scope/A-Scope.class.ts +58 -25
- package/src/global/A-Scope/A-Scope.types.ts +2 -1
- package/src/global/A-Stage/A-Stage.class.ts +225 -0
- package/src/global/A-Stage/A-Stage.types.ts +106 -0
- package/src/helpers/StepsManager.class.ts +104 -0
- package/tests/channel.ts +213 -0
- package/tests/log.ts +88 -40
- package/src/decorators/A-Stage/A-Stage.decorator.ts +0 -84
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { A_CommonHelper } from "@adaas/a-utils";
|
|
1
|
+
import { A_CommonHelper, ASEID } from "@adaas/a-utils";
|
|
2
2
|
import { A_TYPES__ScopeConfig, A_TYPES__ScopeConstructor } from "./A-Scope.types";
|
|
3
3
|
import { A_Fragment } from "../A-Fragment/A-Fragment.class";
|
|
4
4
|
import { A_Context } from "../A-Context/A-Context.class";
|
|
5
5
|
import {
|
|
6
|
-
A_TYPES__ComponentMeta_EntityInjectionInstructions,
|
|
7
|
-
A_TYPES__ComponentMeta_InjectionParam,
|
|
8
6
|
A_TYPES__ComponentMetaKey
|
|
9
7
|
} from "../A-Component/A-Component.types";
|
|
10
8
|
import { A_Component } from "../A-Component/A-Component.class";
|
|
11
9
|
import { A_Entity } from "../A-Entity/A-Entity.class";
|
|
10
|
+
import { A_TYPES__A_InjectDecorator_EntityInjectionInstructions, A_TYPES__A_InjectDecorator_EntityInjectionQuery, A_TYPES__A_InjectDecorator_Injectable } from "@adaas/a-concept/decorators/A-Inject/A-Inject.decorator.types";
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
*
|
|
@@ -72,6 +71,10 @@ export class A_Scope {
|
|
|
72
71
|
// })
|
|
73
72
|
}
|
|
74
73
|
|
|
74
|
+
private initEntities(_entities: Array<A_Entity>) {
|
|
75
|
+
_entities.forEach(this.register.bind(this));
|
|
76
|
+
}
|
|
77
|
+
|
|
75
78
|
|
|
76
79
|
private initFragments(_fragments: Array<A_Fragment>) {
|
|
77
80
|
_fragments.forEach(this.register.bind(this));
|
|
@@ -111,7 +114,7 @@ export class A_Scope {
|
|
|
111
114
|
switch (true) {
|
|
112
115
|
|
|
113
116
|
case A_CommonHelper.isInheritedFrom(entity, A_Component): {
|
|
114
|
-
const found = this.params.components.includes(entity);
|
|
117
|
+
const found = this.params.components.includes(entity as { new(...args: any[]): A_Component });
|
|
115
118
|
|
|
116
119
|
if (!found && !!this.parent)
|
|
117
120
|
return this.parent.has(entity as any);
|
|
@@ -149,20 +152,20 @@ export class A_Scope {
|
|
|
149
152
|
* @param component
|
|
150
153
|
* @returns
|
|
151
154
|
*/
|
|
152
|
-
resolve<T extends
|
|
155
|
+
resolve<T extends A_TYPES__A_InjectDecorator_Injectable>(
|
|
153
156
|
component: T
|
|
154
157
|
): InstanceType<T>
|
|
155
158
|
resolve<T extends { new(...args: any[]): A_Entity }>(
|
|
156
159
|
entity: T,
|
|
157
|
-
instructions: Partial<
|
|
160
|
+
instructions: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions>
|
|
158
161
|
): InstanceType<T>
|
|
159
|
-
resolve<T extends
|
|
162
|
+
resolve<T extends A_TYPES__A_InjectDecorator_Injectable>(
|
|
160
163
|
component: Array<T>
|
|
161
164
|
): Array<InstanceType<T>>
|
|
162
165
|
// base definition
|
|
163
|
-
resolve<T extends
|
|
166
|
+
resolve<T extends A_TYPES__A_InjectDecorator_Injectable>(
|
|
164
167
|
param1: Array<T> | T,
|
|
165
|
-
param2?: string | Partial<
|
|
168
|
+
param2?: string | Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions>
|
|
166
169
|
): Array<InstanceType<T>> | InstanceType<T> {
|
|
167
170
|
|
|
168
171
|
switch (true) {
|
|
@@ -182,16 +185,18 @@ export class A_Scope {
|
|
|
182
185
|
|
|
183
186
|
|
|
184
187
|
|
|
188
|
+
|
|
189
|
+
|
|
185
190
|
private resolveOnce<T extends { new(...args: any[]): A_Entity }>(
|
|
186
191
|
entity: T,
|
|
187
|
-
instructions: Partial<
|
|
192
|
+
instructions: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions>
|
|
188
193
|
): InstanceType<T> | undefined
|
|
189
|
-
private resolveOnce<T extends
|
|
194
|
+
private resolveOnce<T extends A_TYPES__A_InjectDecorator_Injectable>(
|
|
190
195
|
component: T
|
|
191
196
|
): InstanceType<T>
|
|
192
|
-
private resolveOnce<T extends { new(...args: any[]): A_Entity } |
|
|
197
|
+
private resolveOnce<T extends { new(...args: any[]): A_Entity } | A_TYPES__A_InjectDecorator_Injectable>(
|
|
193
198
|
component: T,
|
|
194
|
-
instructions?: Partial<
|
|
199
|
+
instructions?: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions>
|
|
195
200
|
): InstanceType<T> {
|
|
196
201
|
switch (true) {
|
|
197
202
|
case A_CommonHelper.isInheritedFrom(component, A_Entity): {
|
|
@@ -218,9 +223,13 @@ export class A_Scope {
|
|
|
218
223
|
|
|
219
224
|
private resolveEntity<T extends { new(...args: any[]): A_Entity }>(
|
|
220
225
|
entity: T,
|
|
221
|
-
instructions?: Partial<
|
|
226
|
+
instructions?: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions>
|
|
222
227
|
): InstanceType<T> | undefined {
|
|
223
228
|
|
|
229
|
+
const query = instructions?.query || {};
|
|
230
|
+
const count = instructions?.pagination?.count || 1;
|
|
231
|
+
|
|
232
|
+
|
|
224
233
|
switch (true) {
|
|
225
234
|
case !instructions: {
|
|
226
235
|
|
|
@@ -233,25 +242,34 @@ export class A_Scope {
|
|
|
233
242
|
return found as InstanceType<T>;
|
|
234
243
|
|
|
235
244
|
case !found && !!this.parent:
|
|
236
|
-
return this.parent.
|
|
245
|
+
return this.parent.resolveEntity(entity, instructions);
|
|
237
246
|
|
|
238
247
|
default:
|
|
239
248
|
throw new Error(`Fragment ${entity.name} not found in the scope ${this.name}`);
|
|
240
249
|
}
|
|
241
250
|
}
|
|
242
251
|
|
|
243
|
-
case !!
|
|
244
|
-
|
|
245
|
-
|
|
252
|
+
case !!query.aseid
|
|
253
|
+
&& typeof query.aseid === 'string'
|
|
254
|
+
&& this._entities.has(query.aseid): {
|
|
255
|
+
return this._entities.get(query.aseid) as InstanceType<T>;
|
|
256
|
+
}
|
|
246
257
|
|
|
247
|
-
case !!
|
|
248
|
-
|
|
249
|
-
|
|
258
|
+
case !!query.aseid
|
|
259
|
+
&& query.aseid instanceof ASEID
|
|
260
|
+
&& this._entities.has(query.aseid.toString()): {
|
|
261
|
+
return this._entities.get(query.aseid.toString()) as InstanceType<T>;
|
|
262
|
+
}
|
|
250
263
|
|
|
251
|
-
|
|
264
|
+
case !!query.id
|
|
265
|
+
&& this._entities.has(query.id): {
|
|
266
|
+
// in this case we have to find the entity by the id
|
|
267
|
+
const entities = Array.from(this._entities.values());
|
|
252
268
|
|
|
253
|
-
|
|
254
|
-
|
|
269
|
+
const found = entities.find(e => e.id === query.id);
|
|
270
|
+
|
|
271
|
+
return found as InstanceType<T>;
|
|
272
|
+
}
|
|
255
273
|
|
|
256
274
|
default:
|
|
257
275
|
throw new Error(`Entity ${entity.constructor.name} not found in the scope ${this.name}`);
|
|
@@ -331,7 +349,7 @@ export class A_Scope {
|
|
|
331
349
|
|
|
332
350
|
const found = this.components.find(el => A_CommonHelper.isInheritedFrom(el, component));
|
|
333
351
|
|
|
334
|
-
return this.resolveComponent(found
|
|
352
|
+
return this.resolveComponent<T>(found as any);
|
|
335
353
|
}
|
|
336
354
|
|
|
337
355
|
// In case when the component is not available in the scope but the parent is available
|
|
@@ -398,4 +416,19 @@ export class A_Scope {
|
|
|
398
416
|
|
|
399
417
|
|
|
400
418
|
}
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
toJSON(): Record<string, any> {
|
|
424
|
+
return this.fragments.reduce((acc, fragment) => {
|
|
425
|
+
|
|
426
|
+
const serialized = fragment.toJSON()
|
|
427
|
+
|
|
428
|
+
return {
|
|
429
|
+
...acc,
|
|
430
|
+
[serialized.name]: serialized
|
|
431
|
+
}
|
|
432
|
+
}, {});
|
|
433
|
+
}
|
|
401
434
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { A_Component } from "../A-Component/A-Component.class"
|
|
1
2
|
import { A_Fragment } from "../A-Fragment/A-Fragment.class"
|
|
2
3
|
import { A_Scope } from "./A-Scope.class"
|
|
3
4
|
|
|
@@ -15,7 +16,7 @@ export type A_TYPES__ScopeConstructor = {
|
|
|
15
16
|
/**
|
|
16
17
|
* A set of Components available in the Scope
|
|
17
18
|
*/
|
|
18
|
-
components: Array<{ new(...args: any[]):
|
|
19
|
+
components: Array<{ new(...args: any[]): A_Component }>
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { A_CommonHelper, A_Error } from "@adaas/a-utils";
|
|
2
|
+
import { A_Context } from "../A-Context/A-Context.class";
|
|
3
|
+
import { A_Feature } from "../A-Feature/A-Feature.class";
|
|
4
|
+
import { A_TYPES__A_Stage_JSON, A_TYPES__A_Stage_Status, A_TYPES__A_StageStep } from "./A-Stage.types";
|
|
5
|
+
import { A_Container } from "../A-Container/A-Container.class";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A_Stage is a set of A_Functions within A_Feature that should be run in a specific order.
|
|
11
|
+
* Each stage may contain one or more functions.
|
|
12
|
+
* [!] That always run in parallel (in NodeJS asynchronously), independently of each other.
|
|
13
|
+
*
|
|
14
|
+
* A-Stage is a common object that uses to simplify logic and re-use of A-Feature internals for better composition.
|
|
15
|
+
*/
|
|
16
|
+
export class A_Stage {
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
constructor(
|
|
21
|
+
private feature: A_Feature,
|
|
22
|
+
private steps: A_TYPES__A_StageStep[] = []
|
|
23
|
+
) {
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
status: A_TYPES__A_Stage_Status = A_TYPES__A_Stage_Status.INITIALIZED;
|
|
28
|
+
/**
|
|
29
|
+
* Promise that will be resolved when the stage is Processed
|
|
30
|
+
*/
|
|
31
|
+
processed: Promise<void> | undefined;
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
get before(): string[] {
|
|
35
|
+
return this.steps.reduce((acc, step) => ([
|
|
36
|
+
...acc,
|
|
37
|
+
...step.before
|
|
38
|
+
]), [] as string[]);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get after(): string[] {
|
|
42
|
+
return this.steps.reduce((acc, step) => ([
|
|
43
|
+
...acc,
|
|
44
|
+
...step.after
|
|
45
|
+
]), [] as string[]);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Resolves the arguments of the step
|
|
51
|
+
*
|
|
52
|
+
* @param step
|
|
53
|
+
* @returns
|
|
54
|
+
*/
|
|
55
|
+
protected async getStepArgs(step: A_TYPES__A_StageStep) {
|
|
56
|
+
return step.args.map(async arg =>
|
|
57
|
+
// In case if the target is a feature step then pass the current feature
|
|
58
|
+
A_CommonHelper.isInheritedFrom(arg.target, A_Feature)
|
|
59
|
+
? this
|
|
60
|
+
: A_Context.scope(this.feature).resolve(arg.target)
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Adds a step to the stage
|
|
67
|
+
*
|
|
68
|
+
* @param step
|
|
69
|
+
* @returns
|
|
70
|
+
*/
|
|
71
|
+
add(
|
|
72
|
+
step: A_TYPES__A_StageStep
|
|
73
|
+
): this {
|
|
74
|
+
this.steps.push(step);
|
|
75
|
+
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Resolves the component of the step
|
|
82
|
+
*
|
|
83
|
+
* @param step
|
|
84
|
+
* @returns
|
|
85
|
+
*/
|
|
86
|
+
protected getStepInstance(step: A_TYPES__A_StageStep) {
|
|
87
|
+
const { component, handler } = step;
|
|
88
|
+
|
|
89
|
+
// TODO: probably would be better to do it another way. let's think about it
|
|
90
|
+
const instance = component instanceof A_Container
|
|
91
|
+
? component
|
|
92
|
+
: A_Context.scope(this.feature).resolve(component);
|
|
93
|
+
|
|
94
|
+
if (!instance)
|
|
95
|
+
throw new Error(`Unable to resolve component ${component.name}`);
|
|
96
|
+
|
|
97
|
+
if (!instance[handler])
|
|
98
|
+
throw new Error(`Handler ${handler} not found in ${instance.constructor.name}`);
|
|
99
|
+
|
|
100
|
+
return instance;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Calls the handler of the step
|
|
107
|
+
*
|
|
108
|
+
* @param step
|
|
109
|
+
* @returns
|
|
110
|
+
*/
|
|
111
|
+
protected async getStepHandler(step: A_TYPES__A_StageStep) {
|
|
112
|
+
|
|
113
|
+
const instance = this.getStepInstance(step);
|
|
114
|
+
const callArgs = await this.getStepArgs(step);
|
|
115
|
+
|
|
116
|
+
return instance[step.handler](...callArgs);
|
|
117
|
+
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Runs async all the steps of the stage
|
|
123
|
+
*
|
|
124
|
+
* @returns
|
|
125
|
+
*/
|
|
126
|
+
async process(): Promise<void> {
|
|
127
|
+
if (!this.processed)
|
|
128
|
+
this.processed = new Promise<void>(
|
|
129
|
+
async (resolve, reject) => {
|
|
130
|
+
try {
|
|
131
|
+
this.status = A_TYPES__A_Stage_Status.PROCESSING;
|
|
132
|
+
|
|
133
|
+
const syncSteps = this.steps.filter(step => step.behavior === 'sync');
|
|
134
|
+
const asyncSteps = this.steps.filter(step => step.behavior === 'async');
|
|
135
|
+
|
|
136
|
+
// Run sync steps
|
|
137
|
+
|
|
138
|
+
await Promise
|
|
139
|
+
.all([
|
|
140
|
+
|
|
141
|
+
// Run async steps that are independent of each other
|
|
142
|
+
...asyncSteps.map(step => this.getStepHandler(step)),
|
|
143
|
+
|
|
144
|
+
// Run sync steps that are dependent on each other
|
|
145
|
+
new Promise<void>(
|
|
146
|
+
async (r, j) => {
|
|
147
|
+
try {
|
|
148
|
+
for (const step of syncSteps) {
|
|
149
|
+
await this.getStepHandler(step);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return r();
|
|
153
|
+
} catch (error) {
|
|
154
|
+
return j(error);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
)
|
|
158
|
+
]);
|
|
159
|
+
|
|
160
|
+
this.completed();
|
|
161
|
+
|
|
162
|
+
return resolve();
|
|
163
|
+
|
|
164
|
+
} catch (error) {
|
|
165
|
+
this.failed(error);
|
|
166
|
+
|
|
167
|
+
return reject(error);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
return this.processed;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Skips the stage
|
|
178
|
+
*
|
|
179
|
+
*/
|
|
180
|
+
skip() {
|
|
181
|
+
this.status = A_TYPES__A_Stage_Status.SKIPPED;
|
|
182
|
+
|
|
183
|
+
this.feature.next(this);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
// ==========================================
|
|
190
|
+
// ============ Status methods =============
|
|
191
|
+
// ==========================================
|
|
192
|
+
|
|
193
|
+
protected completed() {
|
|
194
|
+
this.status = A_TYPES__A_Stage_Status.COMPLETED;
|
|
195
|
+
|
|
196
|
+
this.feature.next(this);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
protected failed(
|
|
200
|
+
error: Error | A_Error | unknown
|
|
201
|
+
) {
|
|
202
|
+
this.status = A_TYPES__A_Stage_Status.FAILED;
|
|
203
|
+
|
|
204
|
+
this.feature.failed(error);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
// ==========================================
|
|
210
|
+
// ============ Serialization ===============
|
|
211
|
+
// ==========================================
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Serializes the stage to JSON
|
|
216
|
+
*
|
|
217
|
+
*/
|
|
218
|
+
toJSON(): A_TYPES__A_Stage_JSON {
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
name: 'A_Stage',
|
|
222
|
+
status: this.status,
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { A_TYPES__A_InjectDecorator_Meta } from "@adaas/a-concept/decorators/A-Inject/A-Inject.decorator.types"
|
|
2
|
+
import { A_Component } from "../A-Component/A-Component.class"
|
|
3
|
+
import { A_Container } from "../A-Container/A-Container.class"
|
|
4
|
+
import { A_TYPES__A_ExtendDecorator_BehaviorConfig, A_TYPES__A_ExtendDecorator_Meta } from "@adaas/a-concept/decorators/A-Feature/A-Feature.decorator.types"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export enum A_TYPES__A_Stage_Status {
|
|
9
|
+
/**
|
|
10
|
+
* The stage is currently being processed
|
|
11
|
+
*/
|
|
12
|
+
PROCESSING = 'PROCESSING',
|
|
13
|
+
/**
|
|
14
|
+
* The stage has been completed
|
|
15
|
+
*/
|
|
16
|
+
COMPLETED = 'COMPLETED',
|
|
17
|
+
/**
|
|
18
|
+
* The stage has failed
|
|
19
|
+
*/
|
|
20
|
+
FAILED = 'FAILED',
|
|
21
|
+
/**
|
|
22
|
+
* The stage has been skipped
|
|
23
|
+
*/
|
|
24
|
+
SKIPPED = 'SKIPPED',
|
|
25
|
+
/**
|
|
26
|
+
* The stage has been paused
|
|
27
|
+
*/
|
|
28
|
+
// PAUSED = 'PAUSED',
|
|
29
|
+
/**
|
|
30
|
+
* The stage has been stopped
|
|
31
|
+
*/
|
|
32
|
+
// STOPPED = 'STOPPED',
|
|
33
|
+
/**
|
|
34
|
+
* The stage has been started
|
|
35
|
+
*/
|
|
36
|
+
// STARTED = 'STARTED',
|
|
37
|
+
/**
|
|
38
|
+
* The stage has been initialized
|
|
39
|
+
*/
|
|
40
|
+
INITIALIZED = 'INITIALIZED',
|
|
41
|
+
/**
|
|
42
|
+
* The stage has been reset
|
|
43
|
+
*/
|
|
44
|
+
// RESET = 'RESET',
|
|
45
|
+
/**
|
|
46
|
+
* The stage has been resumed
|
|
47
|
+
*/
|
|
48
|
+
// RESUMED = 'RESUMED',
|
|
49
|
+
/**
|
|
50
|
+
* The stage has been suspended
|
|
51
|
+
*/
|
|
52
|
+
// SUSPENDED = 'SUSPENDED',
|
|
53
|
+
/**
|
|
54
|
+
* The stage has been terminated
|
|
55
|
+
*/
|
|
56
|
+
// TERMINATED = 'TERMINATED',
|
|
57
|
+
/**
|
|
58
|
+
* The stage has been aborted
|
|
59
|
+
*/
|
|
60
|
+
ABORTED = 'ABORTED'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
export type A_TYPES__A_StageStep = {
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The component to be called
|
|
68
|
+
*/
|
|
69
|
+
component: typeof A_Component | typeof A_Container | A_Container<any>
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The method to be called on the component
|
|
73
|
+
*/
|
|
74
|
+
handler: string,
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Original Feature Extension name
|
|
78
|
+
*
|
|
79
|
+
* [!] could be string or regex
|
|
80
|
+
*
|
|
81
|
+
*/
|
|
82
|
+
name: string,
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Arguments to be passed to the method
|
|
86
|
+
*/
|
|
87
|
+
args: A_TYPES__A_InjectDecorator_Meta
|
|
88
|
+
|
|
89
|
+
} & A_TYPES__A_ExtendDecorator_BehaviorConfig
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
export type A_TYPES__A_Stage_JSON = {
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* The name of the stage
|
|
97
|
+
*/
|
|
98
|
+
name: string,
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The status of the stage
|
|
102
|
+
*
|
|
103
|
+
*/
|
|
104
|
+
status: A_TYPES__A_Stage_Status,
|
|
105
|
+
|
|
106
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { A_Feature } from "../global/A-Feature/A-Feature.class";
|
|
2
|
+
import { A_Stage } from "../global/A-Stage/A-Stage.class";
|
|
3
|
+
import { A_TYPES__A_StageStep } from "../global/A-Stage/A-Stage.types";
|
|
4
|
+
|
|
5
|
+
export class StepsManager {
|
|
6
|
+
|
|
7
|
+
public entities: A_TYPES__A_StageStep[];
|
|
8
|
+
public graph: Map<string, Set<string>>;
|
|
9
|
+
public visited: Set<string>;
|
|
10
|
+
public tempMark: Set<string>;
|
|
11
|
+
public sortedEntities: string[];
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
constructor(entities: A_TYPES__A_StageStep[]) {
|
|
15
|
+
this.entities = entities;
|
|
16
|
+
this.graph = new Map();
|
|
17
|
+
this.visited = new Set();
|
|
18
|
+
this.tempMark = new Set();
|
|
19
|
+
this.sortedEntities = [];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private buildGraph() {
|
|
23
|
+
// Initialize graph nodes
|
|
24
|
+
this.entities.forEach(entity => this.graph.set(entity.name, new Set()));
|
|
25
|
+
|
|
26
|
+
// Add directed edges based on 'before' and 'after'
|
|
27
|
+
this.entities.forEach(entity => {
|
|
28
|
+
const { name, before = [], after = [] } = entity;
|
|
29
|
+
|
|
30
|
+
// Add edges for 'before' dependencies
|
|
31
|
+
before.forEach(dep => {
|
|
32
|
+
const targets = this.matchEntities(dep);
|
|
33
|
+
targets.forEach(target => {
|
|
34
|
+
if (!this.graph.has(target)) this.graph.set(target, new Set());
|
|
35
|
+
this.graph.get(target)!.add(name); // target -> name (target should be before name)
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Add edges for 'after' dependencies
|
|
40
|
+
after.forEach(dep => {
|
|
41
|
+
const sources = this.matchEntities(dep);
|
|
42
|
+
sources.forEach(source => {
|
|
43
|
+
if (!this.graph.has(name)) this.graph.set(name, new Set());
|
|
44
|
+
this.graph.get(name)!.add(source); // name -> source (name should be before source)
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Match entities by name or regex
|
|
51
|
+
private matchEntities(pattern) {
|
|
52
|
+
const regex = new RegExp(`^${pattern}$`);
|
|
53
|
+
return this.entities
|
|
54
|
+
.filter(entity => regex.test(entity.name))
|
|
55
|
+
.map(entity => entity.name);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Topological sort with cycle detection
|
|
59
|
+
private visit(node) {
|
|
60
|
+
if (this.tempMark.has(node)) throw new Error("Circular dependency detected");
|
|
61
|
+
|
|
62
|
+
if (!this.visited.has(node)) {
|
|
63
|
+
this.tempMark.add(node);
|
|
64
|
+
(this.graph.get(node) || []).forEach(neighbor => this.visit(neighbor));
|
|
65
|
+
this.tempMark.delete(node);
|
|
66
|
+
this.visited.add(node);
|
|
67
|
+
this.sortedEntities.push(node);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Sort the entities based on dependencies
|
|
72
|
+
toStages(feature: A_Feature): Array<A_Stage> {
|
|
73
|
+
this.buildGraph();
|
|
74
|
+
|
|
75
|
+
// Start topological sort
|
|
76
|
+
this.entities.forEach(entity => {
|
|
77
|
+
if (!this.visited.has(entity.name)) this.visit(entity.name);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const stages: A_Stage[] = [];
|
|
81
|
+
|
|
82
|
+
// Map sorted names back to entity objects
|
|
83
|
+
this.sortedEntities
|
|
84
|
+
.map(name => {
|
|
85
|
+
|
|
86
|
+
const step = this.entities.find(entity => entity.name === name)!;
|
|
87
|
+
|
|
88
|
+
let stage = stages.find(stage => {
|
|
89
|
+
return stage.after.every(after => step.after.includes(after))
|
|
90
|
+
&& step.before.every(before => stage.after.includes(before));
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
if (!stage) {
|
|
95
|
+
stage = new A_Stage(feature);
|
|
96
|
+
stages.push(stage);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
stage.add(step);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
return stages;
|
|
103
|
+
}
|
|
104
|
+
}
|