@adaas/a-concept 0.1.17 → 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 (56) 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 +22 -7
  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-Context/A-Context.class.d.ts +8 -0
  14. package/dist/src/global/A-Context/A-Context.class.js +30 -2
  15. package/dist/src/global/A-Context/A-Context.class.js.map +1 -1
  16. package/dist/src/global/A-Feature/A-Feature-Define.decorator.js +1 -1
  17. package/dist/src/global/A-Feature/A-Feature-Define.decorator.js.map +1 -1
  18. package/dist/src/global/A-Feature/A-Feature-Extend.decorator.js +27 -8
  19. package/dist/src/global/A-Feature/A-Feature-Extend.decorator.js.map +1 -1
  20. package/dist/src/global/A-Feature/A-Feature.class.d.ts +2 -1
  21. package/dist/src/global/A-Feature/A-Feature.class.js +7 -3
  22. package/dist/src/global/A-Feature/A-Feature.class.js.map +1 -1
  23. package/dist/src/global/A-Feature/A-Feature.types.d.ts +69 -27
  24. package/dist/src/global/A-Stage/A-Stage.class.d.ts +37 -28
  25. package/dist/src/global/A-Stage/A-Stage.class.js +62 -98
  26. package/dist/src/global/A-Stage/A-Stage.class.js.map +1 -1
  27. package/dist/src/global/A-Stage/A-Stage.types.d.ts +30 -3
  28. package/dist/src/global/A-Stage/A-Stage.types.js.map +1 -1
  29. package/dist/src/global/A-StepManager/A-StepManager.class.d.ts +20 -0
  30. package/dist/src/{helpers/A_StepsManager.class.js → global/A-StepManager/A-StepManager.class.js} +38 -64
  31. package/dist/src/global/A-StepManager/A-StepManager.class.js.map +1 -0
  32. package/dist/src/global/A-StepManager/A-StepManager.error.d.ts +4 -0
  33. package/dist/src/global/A-StepManager/A-StepManager.error.js +9 -0
  34. package/dist/src/global/A-StepManager/A-StepManager.error.js.map +1 -0
  35. package/index.ts +2 -1
  36. package/package.json +3 -3
  37. package/src/global/A-Abstraction/A-Abstraction-Extend.decorator.ts +27 -7
  38. package/src/global/A-Component/A-Component.meta.ts +2 -1
  39. package/src/global/A-Component/A-Component.types.ts +2 -11
  40. package/src/global/A-Concept/A-Concept.types.ts +4 -21
  41. package/src/global/A-Container/A-Container.meta.ts +4 -2
  42. package/src/global/A-Container/A-Container.types.ts +2 -11
  43. package/src/global/A-Context/A-Context.class.ts +40 -3
  44. package/src/global/A-Feature/A-Feature-Define.decorator.ts +1 -0
  45. package/src/global/A-Feature/A-Feature-Extend.decorator.ts +34 -8
  46. package/src/global/A-Feature/A-Feature.class.ts +8 -1
  47. package/src/global/A-Feature/A-Feature.types.ts +80 -33
  48. package/src/global/A-Stage/A-Stage.class.ts +71 -143
  49. package/src/global/A-Stage/A-Stage.types.ts +34 -3
  50. package/src/{helpers/A_StepsManager.class.ts → global/A-StepManager/A-StepManager.class.ts} +53 -87
  51. package/src/global/A-StepManager/A-StepManager.error.ts +10 -0
  52. package/tests/A-Abstraction.test.ts +274 -190
  53. package/tests/A-Feature.test.ts +84 -1
  54. package/tests/A-StepManager.test.ts +346 -0
  55. package/dist/src/helpers/A_StepsManager.class.d.ts +0 -35
  56. package/dist/src/helpers/A_StepsManager.class.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { A_TYPES__A_StageStep } from "../A-Stage/A-Stage.types"
1
+ import { A_TYPES__A_StageStep, A_TYPES_StageExecutionBehavior } from "../A-Stage/A-Stage.types"
2
2
  import { A_Fragment } from "../A-Fragment/A-Fragment.class"
3
3
  import { A_Entity } from "@adaas/a-concept/global/A-Entity/A-Entity.class"
4
4
  import { A_Container } from "../A-Container/A-Container.class"
@@ -206,23 +206,11 @@ export type A_TYPES__FeatureExtendDecoratorDescriptor =
206
206
  * [!] Can be applied only on A-Components
207
207
  */
208
208
  export type A_TYPES__FeatureExtendDecoratorTarget = A_Component
209
- /**
210
- * Meta type for A_Extend decorator
211
- */
212
- export type A_TYPES__FeatureExtendDecoratorMeta = {
213
- /**
214
- * Original Feature Extension name
215
- *
216
- * [!] could be string or regex
217
- */
218
- name: string,
219
- /**
220
- * Actual method name in the class
221
- */
222
- handler: string
223
- } & A_TYPES__FeatureExtendDecoratorBehaviorConfig
209
+
224
210
  /**
225
211
  * Configuration type for A_Extend decorator
212
+ *
213
+ * This is an INPUT parameter provided by the user
226
214
  */
227
215
  export type A_TYPES__FeatureExtendDecoratorConfig = {
228
216
  /**
@@ -253,7 +241,54 @@ export type A_TYPES__FeatureExtendDecoratorConfig = {
253
241
  * ```
254
242
  */
255
243
  scope: Array<A_TYPES__FeatureExtendDecoratorScopeItem> | Partial<A_TYPES__FeatureExtendDecoratorScopeConfig>,
256
- } & A_TYPES__FeatureExtendDecoratorBehaviorConfig
244
+ /**
245
+ * The behavior of the method.
246
+ * In case its async it will be executed independently from the main thread.
247
+ *
248
+ * [!] However, in case of sync, it will be executed in the main thread.in the order of the declaration.
249
+ *
250
+ */
251
+ behavior: A_TYPES_StageExecutionBehavior
252
+ /**
253
+ * Allows to define the order of the execution of the method.
254
+ *
255
+ * [!] It applies for the following structure :'Component.methodName'
256
+ * [!] In case the method has circular dependencies it will Throw an error.
257
+ *
258
+ * Example:
259
+ * ```ts
260
+ * @A_Feature.Extend({
261
+ * name: 'load',
262
+ * before: ['Component1.methodName', /Component2\..+/]
263
+ * })
264
+ * ```
265
+ */
266
+ before: Array<string | RegExp>
267
+
268
+ /**
269
+ * Allows to define the order of the execution of the method.
270
+ *
271
+ * [!] It applies for the following structure :'Component.methodName'
272
+ * [!] In case the method has circular dependencies it will Throw an error.
273
+ *
274
+ * Example:
275
+ * ```ts
276
+ * @A_Feature.Extend({
277
+ * name: 'load',
278
+ * before: ['Component1.methodName', /Component2\..+/]
279
+ * })
280
+ * ```
281
+ *
282
+ */
283
+ after: Array<string | RegExp>
284
+
285
+ /**
286
+ * Indicates whether to throw an error if the step fails.
287
+ *
288
+ * [!] By default is true
289
+ */
290
+ throwOnError: boolean
291
+ }
257
292
  /**
258
293
  * Scope item that can be used in A_Extend decorator configuration
259
294
  */
@@ -270,13 +305,29 @@ export type A_TYPES__FeatureExtendDecoratorScopeConfig = {
270
305
  /**
271
306
  * A single item that can be used in scope configuration
272
307
  */
273
- export type A_TYPES__FeatureExtendDecoratorScopeItem = { new(...args: any[]): A_Container }
274
- | { new(...args: any[]): A_Entity }
275
- | { new(...args: any[]): A_Component }
308
+ export type A_TYPES__FeatureExtendDecoratorScopeItem = A_TYPES__Container_Constructor
309
+ | A_TYPES__Entity_Constructor
310
+ | A_TYPES__Component_Constructor
311
+
312
+
313
+
314
+ // =======================================================================
315
+ // --------------------------META TYPES-----------------------------------
316
+ // =======================================================================
276
317
  /**
277
- * Behavior configuration for A_Extend decorator
318
+ * Meta type for A_Extend decorator
278
319
  */
279
- export type A_TYPES__FeatureExtendDecoratorBehaviorConfig = {
320
+ export type A_TYPES__FeatureExtendDecoratorMeta = {
321
+ /**
322
+ * Original Feature Extension name
323
+ *
324
+ * [!] could be string or regex
325
+ */
326
+ name: string,
327
+ /**
328
+ * Actual method name in the class
329
+ */
330
+ handler: string
280
331
  /**
281
332
  * The behavior of the method.
282
333
  * In case its async it will be executed independently from the main thread.
@@ -284,9 +335,7 @@ export type A_TYPES__FeatureExtendDecoratorBehaviorConfig = {
284
335
  * [!] However, in case of sync, it will be executed in the main thread.in the order of the declaration.
285
336
  *
286
337
  */
287
- behavior: 'async' | 'sync'
288
-
289
-
338
+ behavior: A_TYPES_StageExecutionBehavior
290
339
  /**
291
340
  * Allows to define the order of the execution of the method.
292
341
  *
@@ -294,7 +343,6 @@ export type A_TYPES__FeatureExtendDecoratorBehaviorConfig = {
294
343
  *
295
344
  */
296
345
  before: string[]
297
-
298
346
  /**
299
347
  * Allows to define the order of the execution of the method.
300
348
  *
@@ -302,13 +350,12 @@ export type A_TYPES__FeatureExtendDecoratorBehaviorConfig = {
302
350
  *
303
351
  */
304
352
  after: string[]
353
+ /**
354
+ * Indicates whether to throw an error if the step fails.
355
+ *
356
+ * [!] By default is true
357
+ */
358
+ throwOnError: boolean
305
359
  }
306
360
 
307
361
 
308
-
309
-
310
-
311
-
312
-
313
-
314
-
@@ -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