@adaas/a-concept 0.1.18 → 0.1.19

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.
Files changed (52) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +5 -2
  3. package/dist/index.js.map +1 -1
  4. package/dist/src/global/A-Abstraction/A-Abstraction-Extend.decorator.js +11 -4
  5. package/dist/src/global/A-Abstraction/A-Abstraction-Extend.decorator.js.map +1 -1
  6. package/dist/src/global/A-Component/A-Component.meta.js +2 -1
  7. package/dist/src/global/A-Component/A-Component.meta.js.map +1 -1
  8. package/dist/src/global/A-Component/A-Component.types.d.ts +2 -11
  9. package/dist/src/global/A-Concept/A-Concept.types.d.ts +4 -21
  10. package/dist/src/global/A-Container/A-Container.meta.js +4 -2
  11. package/dist/src/global/A-Container/A-Container.meta.js.map +1 -1
  12. package/dist/src/global/A-Container/A-Container.types.d.ts +2 -11
  13. package/dist/src/global/A-Feature/A-Feature-Define.decorator.js +1 -1
  14. package/dist/src/global/A-Feature/A-Feature-Define.decorator.js.map +1 -1
  15. package/dist/src/global/A-Feature/A-Feature-Extend.decorator.js +14 -5
  16. package/dist/src/global/A-Feature/A-Feature-Extend.decorator.js.map +1 -1
  17. package/dist/src/global/A-Feature/A-Feature.class.d.ts +2 -1
  18. package/dist/src/global/A-Feature/A-Feature.class.js +7 -3
  19. package/dist/src/global/A-Feature/A-Feature.class.js.map +1 -1
  20. package/dist/src/global/A-Feature/A-Feature.types.d.ts +69 -27
  21. package/dist/src/global/A-Stage/A-Stage.class.d.ts +37 -28
  22. package/dist/src/global/A-Stage/A-Stage.class.js +62 -98
  23. package/dist/src/global/A-Stage/A-Stage.class.js.map +1 -1
  24. package/dist/src/global/A-Stage/A-Stage.types.d.ts +30 -3
  25. package/dist/src/global/A-Stage/A-Stage.types.js.map +1 -1
  26. package/dist/src/global/A-StepManager/A-StepManager.class.d.ts +20 -0
  27. package/dist/src/{helpers/A_StepsManager.class.js → global/A-StepManager/A-StepManager.class.js} +38 -64
  28. package/dist/src/global/A-StepManager/A-StepManager.class.js.map +1 -0
  29. package/dist/src/global/A-StepManager/A-StepManager.error.d.ts +4 -0
  30. package/dist/src/global/A-StepManager/A-StepManager.error.js +9 -0
  31. package/dist/src/global/A-StepManager/A-StepManager.error.js.map +1 -0
  32. package/index.ts +2 -1
  33. package/package.json +3 -3
  34. package/src/global/A-Abstraction/A-Abstraction-Extend.decorator.ts +18 -6
  35. package/src/global/A-Component/A-Component.meta.ts +2 -1
  36. package/src/global/A-Component/A-Component.types.ts +2 -11
  37. package/src/global/A-Concept/A-Concept.types.ts +4 -21
  38. package/src/global/A-Container/A-Container.meta.ts +4 -2
  39. package/src/global/A-Container/A-Container.types.ts +2 -11
  40. package/src/global/A-Feature/A-Feature-Define.decorator.ts +1 -0
  41. package/src/global/A-Feature/A-Feature-Extend.decorator.ts +21 -7
  42. package/src/global/A-Feature/A-Feature.class.ts +8 -1
  43. package/src/global/A-Feature/A-Feature.types.ts +80 -33
  44. package/src/global/A-Stage/A-Stage.class.ts +71 -143
  45. package/src/global/A-Stage/A-Stage.types.ts +34 -3
  46. package/src/{helpers/A_StepsManager.class.ts → global/A-StepManager/A-StepManager.class.ts} +53 -87
  47. package/src/global/A-StepManager/A-StepManager.error.ts +10 -0
  48. package/tests/A-Abstraction.test.ts +273 -255
  49. package/tests/A-Feature.test.ts +270 -271
  50. package/tests/A-StepManager.test.ts +346 -0
  51. package/dist/src/helpers/A_StepsManager.class.d.ts +0 -35
  52. package/dist/src/helpers/A_StepsManager.class.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import {
2
- A_TYPES__A_Stage_JSON, A_TYPES__A_Stage_Status,
3
- A_TYPES__A_StageStep, A_TYPES__A_StageStepProcessingExtraParams
2
+ A_TYPES__A_Stage_Status,
3
+ A_TYPES__A_StageStep,
4
+ A_TYPES__Stage_Serialized
4
5
  } from "./A-Stage.types";
5
6
  import { A_Context } from "../A-Context/A-Context.class";
6
7
  import { A_Feature } from "../A-Feature/A-Feature.class";
@@ -16,64 +17,60 @@ import { A_TYPES__Component_Constructor } from "../A-Component/A-Component.types
16
17
 
17
18
  export class A_Stage {
18
19
 
20
+ /**
21
+ * The feature that owns this stage
22
+ */
19
23
  private readonly _feature!: A_Feature;
20
- private readonly _steps!: A_TYPES__A_StageStep[];
24
+ /**
25
+ * Initial Instructions to process the stage
26
+ */
27
+ private readonly _definition!: A_TYPES__A_StageStep;
28
+ /**
29
+ * Possible errors during stage processing
30
+ */
21
31
  private _error?: Error | A_Error | any;
32
+ /**
33
+ * Indicates the current status of the stage
34
+ */
35
+ private _status: A_TYPES__A_Stage_Status = A_TYPES__A_Stage_Status.INITIALIZED;
36
+
37
+ /**
38
+ * Promise that will be resolved when the stage is Processed
39
+ */
40
+ private _processed: Promise<void> | undefined;
22
41
 
23
42
 
24
43
  /**
25
- * A_Stage is a set of A_Functions within A_Feature that should be run in a specific order.
26
- * Each stage may contain one or more functions.
27
- * [!] That always run in parallel (in NodeJS asynchronously), independently of each other.
44
+ * A_Stage is a callable A_Function within A_Feature that should be run with specific parameters.
45
+ * [!] Depending on the Stage Definition type sync/async function can be executed correspondingly.
28
46
  *
29
47
  * A-Stage is a common object that uses to simplify logic and re-use of A-Feature internals for better composition.
30
48
  */
31
49
  constructor(
50
+ /**
51
+ * The feature that owns this stage
52
+ */
32
53
  feature: A_Feature,
33
- steps: A_TYPES__A_StageStep[] = []
54
+ /**
55
+ * The step definitions of the stage
56
+ */
57
+ step: A_TYPES__A_StageStep
34
58
  ) {
35
59
  this._feature = feature;
36
- this._steps = steps;
60
+ this._definition = step;
37
61
  }
38
62
 
39
- status: A_TYPES__A_Stage_Status = A_TYPES__A_Stage_Status.INITIALIZED;
40
-
41
63
  /**
42
- * Promise that will be resolved when the stage is Processed
64
+ * Returns the name of the stage
43
65
  */
44
- processed: Promise<void> | undefined;
45
-
46
-
47
-
48
-
49
66
  get name(): string {
50
67
  return this.toString();
51
68
  }
52
-
53
- get before(): string[] {
54
- return this._steps.reduce((acc, step) => ([
55
- ...acc,
56
- ...step.before
57
- ]), [] as string[]);
58
- }
59
-
60
- get after(): string[] {
61
- return this._steps.reduce((acc, step) => ([
62
- ...acc,
63
- ...step.after
64
- ]), [] as string[]);
65
- }
66
-
67
- get steps(): A_TYPES__A_StageStep[] {
68
- return this._steps;
69
- }
70
-
71
- get asyncSteps(): A_TYPES__A_StageStep[] {
72
- return this._steps.filter(step => step.behavior === 'async');
73
- }
74
-
75
- get syncSteps(): A_TYPES__A_StageStep[] {
76
- return this._steps.filter(step => step.behavior === 'sync');
69
+ /**
70
+ * Returns the current status of the stage
71
+ */
72
+ get status(): A_TYPES__A_Stage_Status {
73
+ return this._status;
77
74
  }
78
75
 
79
76
 
@@ -130,28 +127,13 @@ export class A_Stage {
130
127
  }
131
128
 
132
129
 
133
- /**
134
- * Adds a step to the stage
135
- *
136
- * @param step
137
- * @returns
138
- */
139
- add(
140
- step: A_TYPES__A_StageStep
141
- ): this {
142
- this._steps.push(step);
143
-
144
- return this;
145
- }
146
-
147
-
148
130
  /**
149
131
  * Resolves the component of the step
150
132
  *
151
133
  * @param step
152
134
  * @returns
153
135
  */
154
- protected getStepInstance(
136
+ protected getStepComponent(
155
137
  scope: A_Scope,
156
138
  step: A_TYPES__A_StageStep
157
139
  ) {
@@ -194,15 +176,18 @@ export class A_Stage {
194
176
  step: A_TYPES__A_StageStep,
195
177
  scope: A_Scope
196
178
  ) {
197
- const instance = await this.getStepInstance(scope, step);
179
+ // 1) Resolve component
180
+ const component = await this.getStepComponent(scope, step);
181
+ // 2) Resolve arguments
198
182
  const callArgs = await this.getStepArgs(scope, step);
199
183
 
200
- return await instance[step.handler](...callArgs);
184
+ // 3) Call handler
185
+ return await component[step.handler](...callArgs);
201
186
  }
202
187
 
203
188
 
204
189
  skip() {
205
- this.status = A_TYPES__A_Stage_Status.SKIPPED;
190
+ this._status = A_TYPES__A_Stage_Status.SKIPPED;
206
191
  }
207
192
 
208
193
 
@@ -216,86 +201,44 @@ export class A_Stage {
216
201
  * Scope to be used to resolve the steps dependencies
217
202
  */
218
203
  scope?: A_Scope,
219
- ): Promise<void>
220
- async process(
221
- /**
222
- * Extra parameters to control the steps processing
223
- */
224
- params?: Partial<A_TYPES__A_StageStepProcessingExtraParams>
225
- ): Promise<void>
226
- async process(
227
- /**
228
- * Scope to be used to resolve the steps dependencies
229
- */
230
- param1?: A_Scope | Partial<A_TYPES__A_StageStepProcessingExtraParams>,
231
- /**
232
- * Extra parameters to control the steps processing
233
- */
234
- param2?: Partial<A_TYPES__A_StageStepProcessingExtraParams>
235
204
  ): Promise<void> {
236
205
 
237
- const scope = A_TypeGuards.isScopeInstance(param1)
238
- ? param1
206
+ const targetScope = A_TypeGuards.isScopeInstance(scope)
207
+ ? scope
239
208
  : A_Context.scope(this._feature);
240
209
 
241
- const params = A_TypeGuards.isScopeInstance(param1)
242
- ? param2
243
- : param1;
244
-
245
-
246
- if (!this.processed)
247
- this.processed = new Promise<void>(
210
+ if (!this._processed)
211
+ this._processed = new Promise<void>(
248
212
  async (resolve, reject) => {
249
213
  try {
250
- this.status = A_TYPES__A_Stage_Status.PROCESSING;
251
-
252
- if (params?.steps && params.steps.length) {
253
- params.steps.forEach(step => this.add(step));
214
+ this._status = A_TYPES__A_Stage_Status.PROCESSING;
215
+
216
+ if (this._definition.behavior === 'sync') {
217
+ // in case we have to wait for the result
218
+ await this.callStepHandler(this._definition, targetScope);
219
+ } else {
220
+ // in case we don't have to wait for the result
221
+ this.callStepHandler(this._definition, targetScope);
254
222
  }
255
223
 
256
- const syncSteps = this.syncSteps.filter(params?.filter || (() => true));
257
- const asyncSteps = this.asyncSteps.filter(params?.filter || (() => true));
258
-
259
- // Run sync _steps
260
- await Promise
261
- .all([
262
-
263
- // Run async _steps that are independent of each other
264
- ...asyncSteps.map(step => this.callStepHandler(step, scope)),
265
-
266
- // Run sync _steps that are dependent on each other
267
- new Promise<void>(
268
- async (r, j) => {
269
- try {
270
- for (const step of syncSteps) {
271
- // console.log(' - -> Processing stage step:', step.handler, ' with Regexp: ', step.name);
272
-
273
- await this.callStepHandler(step, scope);
274
-
275
- // console.log(' - -> Finished processing stage step:', step.handler);
276
- }
277
-
278
- return r();
279
- } catch (error) {
280
-
281
- return j(error);
282
- }
283
- }
284
- )
285
- ]);
286
-
287
224
  this.completed();
288
225
 
289
226
  return resolve();
290
227
  } catch (error) {
291
- this.failed(error);
228
+ const wrappedError = new A_Error(error as any);
292
229
 
293
- return reject(error);
230
+ this.failed(wrappedError);
231
+
232
+
233
+ if (this._definition.throwOnError) {
234
+ return resolve();
235
+ } else {
236
+ return reject(wrappedError);
237
+ }
294
238
  }
295
239
  });
296
240
 
297
-
298
- return this.processed;
241
+ return this._processed;
299
242
  }
300
243
 
301
244
 
@@ -304,7 +247,7 @@ export class A_Stage {
304
247
  // ==========================================
305
248
 
306
249
  protected completed() {
307
- this.status = A_TYPES__A_Stage_Status.COMPLETED;
250
+ this._status = A_TYPES__A_Stage_Status.COMPLETED;
308
251
  }
309
252
 
310
253
  protected failed(
@@ -312,7 +255,7 @@ export class A_Stage {
312
255
  ) {
313
256
  this._error = error;
314
257
 
315
- this.status = A_TYPES__A_Stage_Status.FAILED;
258
+ this._status = A_TYPES__A_Stage_Status.FAILED;
316
259
  }
317
260
 
318
261
 
@@ -324,7 +267,7 @@ export class A_Stage {
324
267
  * Serializes the stage to JSON
325
268
  *
326
269
  */
327
- toJSON(): A_TYPES__A_Stage_JSON {
270
+ toJSON(): A_TYPES__Stage_Serialized {
328
271
  return {
329
272
  name: this.name,
330
273
  status: this.status,
@@ -337,21 +280,6 @@ export class A_Stage {
337
280
  * @returns
338
281
  */
339
282
  toString() {
340
- return [
341
- this._feature.name,
342
- '::a-stage:',
343
- '[sync:',
344
- this
345
- .syncSteps
346
- .map(s => typeof s.component === 'string' ? s.component : s.component.name + '.' + s.handler)
347
- .join(' -> '),
348
- ']',
349
- '[async:',
350
- this
351
- .asyncSteps
352
- .map(s => typeof s.component === 'string' ? s.component : s.component.name + '.' + s.handler)
353
- .join(' -> '),
354
- ']'
355
- ].join('');
283
+ return `A-Stage(${this._feature.name}::${this._definition.behavior}@${this._definition.handler})`;
356
284
  }
357
285
  }
@@ -1,6 +1,5 @@
1
1
  import { A_Container } from "../A-Container/A-Container.class"
2
2
  import { A_TYPES__Component_Constructor } from "../A-Component/A-Component.types"
3
- import { A_TYPES__FeatureExtendDecoratorBehaviorConfig } from "../A-Feature/A-Feature.types"
4
3
 
5
4
 
6
5
 
@@ -43,6 +42,8 @@ export enum A_TYPES__A_Stage_Status {
43
42
  ABORTED = 'ABORTED'
44
43
  }
45
44
 
45
+ export type A_TYPES_StageExecutionBehavior = 'async' | 'sync'
46
+
46
47
 
47
48
  export type A_TYPES__A_StageStep = {
48
49
  /**
@@ -61,11 +62,41 @@ export type A_TYPES__A_StageStep = {
61
62
  */
62
63
  name: string,
63
64
 
64
- } & A_TYPES__FeatureExtendDecoratorBehaviorConfig
65
+ /**
66
+ * In case its async it will be executed independently from the main thread.
67
+ *
68
+ * [!] However, in case of sync, it will be executed in the main thread.in the order of the declaration.
69
+ *
70
+ */
71
+ behavior: A_TYPES_StageExecutionBehavior
72
+
73
+ /**
74
+ * Allows to define the order of the execution of the method.
75
+ *
76
+ * [!] In case the method has circular dependencies it will Throw an error.
77
+ *
78
+ */
79
+ before: string[]
80
+
81
+ /**
82
+ * Allows to define the order of the execution of the method.
83
+ *
84
+ * [!] In case the method has circular dependencies it will Throw an error.
85
+ *
86
+ */
87
+ after: string[],
88
+
89
+ /**
90
+ * Indicates whether to throw an error if the step fails.
91
+ *
92
+ * [!] By default is true
93
+ */
94
+ throwOnError: boolean
95
+ }
65
96
 
66
97
 
67
98
 
68
- export type A_TYPES__A_Stage_JSON = {
99
+ export type A_TYPES__Stage_Serialized = {
69
100
 
70
101
  /**
71
102
  * The name of the stage
@@ -1,8 +1,8 @@
1
- import { A_Error } from "../global/A-Error/A_Error.class";
2
- import { A_Feature } from "../global/A-Feature/A-Feature.class";
3
- import { A_TYPES__FeatureDefineDecoratorTemplateItem } from "../global/A-Feature/A-Feature.types";
4
- import { A_Stage } from "../global/A-Stage/A-Stage.class";
5
- import { A_TYPES__A_StageStep } from "../global/A-Stage/A-Stage.types";
1
+ import { A_Feature } from "../A-Feature/A-Feature.class";
2
+ import { A_TYPES__FeatureDefineDecoratorTemplateItem } from "../A-Feature/A-Feature.types";
3
+ import { A_Stage } from "../A-Stage/A-Stage.class";
4
+ import { A_TYPES__A_StageStep } from "../A-Stage/A-Stage.types";
5
+ import { A_StepManagerError } from "./A-StepManager.error";
6
6
 
7
7
  export class A_StepsManager {
8
8
 
@@ -13,6 +13,8 @@ export class A_StepsManager {
13
13
  public sortedEntities: string[];
14
14
 
15
15
 
16
+ private _isBuilt: boolean = false;
17
+
16
18
  constructor(entities: Array<A_TYPES__FeatureDefineDecoratorTemplateItem>) {
17
19
  this.entities = this.prepareSteps(entities);
18
20
 
@@ -29,10 +31,11 @@ export class A_StepsManager {
29
31
  return entities.map(step => {
30
32
  return {
31
33
  ...step,
32
-
34
+
33
35
  behavior: step.behavior || 'sync',
34
36
  before: step.before || [],
35
37
  after: step.after || [],
38
+ throwOnError: false
36
39
  };
37
40
  });
38
41
  }
@@ -42,6 +45,8 @@ export class A_StepsManager {
42
45
  }
43
46
 
44
47
  private buildGraph() {
48
+ if (this._isBuilt) return;
49
+ this._isBuilt = true;
45
50
  // Initialize graph nodes
46
51
  this.entities.forEach(entity => this.graph.set(this.ID(entity), new Set()));
47
52
 
@@ -54,7 +59,7 @@ export class A_StepsManager {
54
59
  // If entity should execute before targets, then targets depend on entity
55
60
  // So we add edges: target -> entity (target depends on entity)
56
61
  before.forEach(dep => {
57
- const targets = this.matchEntities(dep);
62
+ const targets = this.matchEntities(entityId, dep);
58
63
  targets.forEach(target => {
59
64
  if (!this.graph.has(target)) this.graph.set(target, new Set());
60
65
  this.graph.get(target)!.add(entityId); // target depends on entity
@@ -65,7 +70,7 @@ export class A_StepsManager {
65
70
  // If entity should execute after sources, then entity depends on sources
66
71
  // So we add edges: entity -> source (entity depends on source)
67
72
  after.forEach(dep => {
68
- const sources = this.matchEntities(dep);
73
+ const sources = this.matchEntities(entityId, dep);
69
74
 
70
75
  sources.forEach(source => {
71
76
  if (!this.graph.has(entityId)) this.graph.set(entityId, new Set());
@@ -76,28 +81,51 @@ export class A_StepsManager {
76
81
  }
77
82
 
78
83
  // Match entities by name or regex
79
- private matchEntities(pattern: string): string[] {
80
- const regex = new RegExp(`^${pattern}$`);
84
+ private matchEntities(entityId: string, pattern: string): string[] {
85
+ const regex = new RegExp(pattern);
86
+
81
87
  return this.entities
82
- .filter(entity => regex.test(this.ID(entity)))
88
+ .filter(entity => regex.test(this.ID(entity)) && this.ID(entity) !== entityId)
83
89
  .map(entity => this.ID(entity));
84
90
  }
85
91
 
86
92
  // Topological sort with cycle detection
87
93
  private visit(node: string): void {
88
- if (this.tempMark.has(node)) throw new A_Error("Circular dependency detected");
94
+ if (this.tempMark.has(node)) {
95
+ return;
96
+ // TODO: maybe we have to keep this error but only for partial cases
97
+ throw new A_StepManagerError(
98
+ A_StepManagerError.CircularDependencyError,
99
+ `Circular dependency detected involving step: ${node}. Make sure that your 'before' and 'after' dependencies do not create cycles.`
100
+ );
101
+ }
89
102
 
90
103
  if (!this.visited.has(node)) {
91
104
  this.tempMark.add(node);
105
+
106
+
92
107
  (this.graph.get(node) || []).forEach(neighbor => this.visit(neighbor));
93
108
  this.tempMark.delete(node);
94
109
  this.visited.add(node);
95
110
  this.sortedEntities.push(node);
111
+
112
+ // // Visit neighbors in stable order (preserving original order)
113
+ // const neighbors = Array.from(this.graph.get(node) || []);
114
+ // // neighbors.sort((a, b) => {
115
+ // // const orderA = this.originalOrder.get(a) || 0;
116
+ // // const orderB = this.originalOrder.get(b) || 0;
117
+ // // return orderA - orderB;
118
+ // // });
119
+
120
+ // neighbors.forEach(neighbor => this.visit(neighbor));
121
+ // this.tempMark.delete(node);
122
+ // this.visited.add(node);
123
+ // this.sortedEntities.push(node);
96
124
  }
97
125
  }
98
126
 
99
- // Sort the entities based on dependencies
100
- toStages(feature: A_Feature): Array<A_Stage> {
127
+
128
+ toSortedArray(): Array<string> {
101
129
  this.buildGraph();
102
130
 
103
131
  // Start topological sort
@@ -105,87 +133,25 @@ export class A_StepsManager {
105
133
  if (!this.visited.has(this.ID(entity))) this.visit(this.ID(entity));
106
134
  });
107
135
 
108
- const stages: A_TmpStage[] = [];
109
-
110
- // Map sorted names back to entity objects
111
- this.sortedEntities
112
- .map(id => {
113
- const step = this.entities.find(entity => this.ID(entity) === id)!;
114
-
115
- let stage = stages.find(stage => {
116
- return stage.after.every(after => step.after.includes(after))
117
- && step.before.every(before => stage.after.includes(before));
118
- });
119
-
120
-
121
- if (!stage) {
122
- stage = new A_TmpStage();
123
- stages.push(stage);
124
- }
125
-
126
- stage.add(step);
127
- });
128
-
129
- return stages.map(stage => new A_Stage(feature, stage.steps));
130
- }
131
- }
132
-
133
-
134
-
135
-
136
-
137
- export class A_TmpStage {
138
-
139
- readonly name: string = 'A_TmpStage';
140
-
141
- private readonly _steps!: A_TYPES__A_StageStep[];
142
-
143
- constructor(
144
- _steps: A_TYPES__A_StageStep[] = []
145
- ) {
146
- this._steps = _steps;
136
+ return this.sortedEntities;
147
137
  }
148
138
 
139
+ // Sort the entities based on dependencies
140
+ toStages(feature: A_Feature): Array<A_Stage> {
149
141
 
150
- get before(): string[] {
151
- return this._steps.reduce((acc, step) => ([
152
- ...acc,
153
- ...step.before
154
- ]), [] as string[]);
155
- }
156
142
 
157
- get after(): string[] {
158
- return this._steps.reduce((acc, step) => ([
159
- ...acc,
160
- ...step.after
161
- ]), [] as string[]);
162
- }
143
+ const sortedNames = this.toSortedArray();
163
144
 
164
- get steps(): A_TYPES__A_StageStep[] {
165
- return this._steps;
166
- }
167
145
 
146
+ // Map sorted names back to entity objects
147
+ return sortedNames
148
+ .map(id => {
149
+ const step = this.entities.find(entity => this.ID(entity) === id)!;
168
150
 
169
- get asyncSteps(): A_TYPES__A_StageStep[] {
170
- return this._steps.filter(step => step.behavior === 'async');
171
- }
172
151
 
173
- get syncSteps(): A_TYPES__A_StageStep[] {
174
- return this._steps.filter(step => step.behavior === 'sync');
152
+ return new A_Stage(feature, step);
153
+ });
175
154
  }
155
+ }
176
156
 
177
157
 
178
- /**
179
- * Adds a step to the stage
180
- *
181
- * @param step
182
- * @returns
183
- */
184
- add(
185
- step: A_TYPES__A_StageStep
186
- ): this {
187
- this._steps.push(step);
188
-
189
- return this;
190
- }
191
- }
@@ -0,0 +1,10 @@
1
+ import { A_Error } from "../A-Error/A_Error.class";
2
+
3
+
4
+
5
+ export class A_StepManagerError extends A_Error {
6
+
7
+
8
+ static readonly CircularDependencyError = 'A-StepManager Circular Dependency Error';
9
+
10
+ }