@adaas/a-concept 0.0.59 → 0.0.61

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 (66) hide show
  1. package/dist/index.d.ts +5 -0
  2. package/dist/index.js +8 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/src/decorators/A-Feature/A-Feature-Define.decorator.d.ts +2 -1
  5. package/dist/src/decorators/A-Feature/A-Feature-Define.decorator.js +9 -2
  6. package/dist/src/decorators/A-Feature/A-Feature-Define.decorator.js.map +1 -1
  7. package/dist/src/{base/A-Command/A_Command.entity.d.ts → global/A-Command/A-Command.class.d.ts} +72 -10
  8. package/dist/src/{base/A-Command/A_Command.entity.js → global/A-Command/A-Command.class.js} +119 -46
  9. package/dist/src/global/A-Command/A-Command.class.js.map +1 -0
  10. package/dist/src/{base/A-Command/A_Command.constants.js → global/A-Command/A-Command.constants.js} +1 -1
  11. package/dist/src/global/A-Command/A-Command.constants.js.map +1 -0
  12. package/dist/src/global/A-Command/A-Command.meta.d.ts +11 -0
  13. package/dist/src/global/A-Command/A-Command.meta.js +18 -0
  14. package/dist/src/global/A-Command/A-Command.meta.js.map +1 -0
  15. package/dist/src/global/A-Command/A-Command.types.d.ts +43 -0
  16. package/dist/src/global/A-Command/A-Command.types.js +10 -0
  17. package/dist/src/global/A-Command/A-Command.types.js.map +1 -0
  18. package/dist/src/{base → global}/A-Command/context/A_Command.context.d.ts +1 -1
  19. package/dist/src/{base → global}/A-Command/context/A_Command.context.js +1 -1
  20. package/dist/src/global/A-Command/context/A_Command.context.js.map +1 -0
  21. package/dist/src/global/A-Concept/A_Concept.class.js +2 -0
  22. package/dist/src/global/A-Concept/A_Concept.class.js.map +1 -1
  23. package/dist/src/global/A-Concept/A_Concept.types.d.ts +10 -0
  24. package/dist/src/global/A-Concept/A_Concept.types.js.map +1 -1
  25. package/dist/src/global/A-Context/A-Context.class.d.ts +3 -1
  26. package/dist/src/global/A-Context/A-Context.class.js +16 -6
  27. package/dist/src/global/A-Context/A-Context.class.js.map +1 -1
  28. package/dist/src/global/A-Entity/A-Entity.class.js +1 -4
  29. package/dist/src/global/A-Entity/A-Entity.class.js.map +1 -1
  30. package/dist/src/global/A-Feature/A-FeatureCaller.class.d.ts +4 -3
  31. package/dist/src/global/A-Feature/A-FeatureCaller.class.js.map +1 -1
  32. package/dist/src/global/A-Scope/A-Scope.class.d.ts +23 -0
  33. package/dist/src/global/A-Scope/A-Scope.class.js +87 -1
  34. package/dist/src/global/A-Scope/A-Scope.class.js.map +1 -1
  35. package/dist/src/global/A-Scope/A-Scope.types.d.ts +7 -0
  36. package/dist/src/global/A-Stage/A-Stage.class.d.ts +1 -1
  37. package/index.ts +9 -0
  38. package/package.json +2 -2
  39. package/src/decorators/A-Feature/A-Feature-Define.decorator.ts +13 -6
  40. package/src/{base/A-Command/A_Command.entity.ts → global/A-Command/A-Command.class.ts} +149 -35
  41. package/src/global/A-Command/A-Command.meta.ts +22 -0
  42. package/src/global/A-Command/A-Command.types.ts +71 -0
  43. package/src/global/A-Concept/A_Concept.class.ts +3 -0
  44. package/src/global/A-Concept/A_Concept.types.ts +10 -0
  45. package/src/global/A-Context/A-Context.class.ts +23 -5
  46. package/src/global/A-Entity/A-Entity.class.ts +1 -4
  47. package/src/global/A-Feature/A-FeatureCaller.class.ts +4 -3
  48. package/src/global/A-Scope/A-Scope.class.ts +119 -5
  49. package/src/global/A-Scope/A-Scope.types.ts +7 -0
  50. package/tests/A-Command.test.ts +15 -11
  51. package/tests/A-Concept.test.ts +110 -0
  52. package/tests/A-Scope.test.ts +64 -1
  53. package/dist/src/base/A-Command/A_Command.constants.js.map +0 -1
  54. package/dist/src/base/A-Command/A_Command.entity.js.map +0 -1
  55. package/dist/src/base/A-Command/A_Command.types.d.ts +0 -15
  56. package/dist/src/base/A-Command/A_Command.types.js +0 -3
  57. package/dist/src/base/A-Command/A_Command.types.js.map +0 -1
  58. package/dist/src/base/A-Command/context/A_Command.context.js.map +0 -1
  59. package/dist/src/base/A-Command/context/A_CommandFactory.context.d.ts +0 -0
  60. package/dist/src/base/A-Command/context/A_CommandFactory.context.js +0 -2
  61. package/dist/src/base/A-Command/context/A_CommandFactory.context.js.map +0 -1
  62. package/src/base/A-Command/A_Command.types.ts +0 -34
  63. package/src/base/A-Command/context/A_CommandFactory.context.ts +0 -0
  64. /package/dist/src/{base/A-Command/A_Command.constants.d.ts → global/A-Command/A-Command.constants.d.ts} +0 -0
  65. /package/src/{base/A-Command/A_Command.constants.ts → global/A-Command/A-Command.constants.ts} +0 -0
  66. /package/src/{base → global}/A-Command/context/A_Command.context.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaas/a-concept",
3
- "version": "0.0.59",
3
+ "version": "0.0.61",
4
4
  "description": "A-Concept is a framework to build new Applications within or outside the ADAAS ecosystem. This framework is designed to be modular structure regardless environment and program goal.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "homepage": "https://github.com/ADAAS-org/adaas-adf-auth#readme",
53
53
  "dependencies": {
54
- "@adaas/a-utils": "^0.0.7",
54
+ "@adaas/a-utils": "^0.0.8",
55
55
  "@types/node": "^20.10.0"
56
56
  },
57
57
  "devDependencies": {
@@ -14,6 +14,9 @@ import { A_ComponentMeta } from "@adaas/a-concept/global/A-Component/A-Component
14
14
  import { A_TYPES__EntityMetaKey } from "@adaas/a-concept/global/A-Entity/A-Entity.types";
15
15
  import { A_TYPES__ComponentMetaKey } from "@adaas/a-concept/global/A-Component/A-Component.types";
16
16
  import { A_Meta } from "@adaas/a-concept/global/A-Meta/A-Meta.class";
17
+ import { A_Command } from "@adaas/a-concept/global/A-Command/A-Command.class";
18
+ import { A_TYPES__CommandMetaKey } from "@adaas/a-concept/global/A-Command/A-Command.types";
19
+ import { A_CommandMeta } from "@adaas/a-concept/global/A-Command/A-Command.meta";
17
20
 
18
21
  /**
19
22
  * A-Feature decorator
@@ -32,12 +35,12 @@ export function A_Feature_Define(
32
35
  config: Partial<A_TYPES__A_FeatureDecoratorConfig> = {}
33
36
  ) {
34
37
  return function (
35
- target: A_Container | A_Entity | A_Component,
38
+ target: A_Container | A_Entity | A_Component | A_Command,
36
39
  propertyKey: string,
37
40
  descriptor: A_TYPES__A_FeatureDecoratorDescriptor
38
41
  ) {
39
42
 
40
- const meta: A_EntityMeta | A_ContainerMeta | A_ComponentMeta = A_Context.meta(target.constructor as any);
43
+ const meta: A_EntityMeta | A_ContainerMeta | A_ComponentMeta | A_CommandMeta = A_Context.meta(target.constructor as any);
41
44
 
42
45
  let metaKey;
43
46
 
@@ -52,8 +55,13 @@ export function A_Feature_Define(
52
55
  case target instanceof A_Component:
53
56
  metaKey = A_TYPES__ComponentMetaKey.FEATURES
54
57
  break;
55
- default:
56
- throw new Error(`A-Feature cannot be defined on the ${target} level`);
58
+ case target instanceof A_Command:
59
+ metaKey = A_TYPES__CommandMetaKey.FEATURES
60
+ break;
61
+ default: {
62
+ console.log(target);
63
+ throw new Error(`A-Feature cannot be defined on the ${(target as any).constructor.name} level`);
64
+ }
57
65
  }
58
66
 
59
67
 
@@ -72,7 +80,7 @@ export function A_Feature_Define(
72
80
  const handlerName = config.name || propertyKey;
73
81
  // default to false
74
82
  const invoke = config.invoke || false;
75
-
83
+
76
84
 
77
85
  // Set the metadata of the method to define a custom Feature with name
78
86
  existedMeta.set(propertyKey, {
@@ -102,7 +110,6 @@ export function A_Feature_Define(
102
110
  const originalMethod = descriptor.value!;
103
111
 
104
112
 
105
-
106
113
  // Wrap the original method to add the call to `call`
107
114
  // this helps to automatically call the container/entity/component method when it's called
108
115
  descriptor.value = function (...args: any[]) {
@@ -1,21 +1,69 @@
1
- import { A_Entity } from "@adaas/a-concept/global/A-Entity/A-Entity.class";
2
- import { A_TYPES__Command_Constructor, A_TYPES__Command_Listener, A_TYPES__Command_Serialized } from "./A_Command.types";
3
- import { A_Error } from "@adaas/a-utils";
1
+ import { A_TYPES__Command_Constructor, A_TYPES__Command_Listener, A_TYPES__Command_Serialized } from "./A-Command.types";
2
+ import { A_CommonHelper, A_Error, ASEID } from "@adaas/a-utils";
4
3
  import { A_Scope } from "@adaas/a-concept/global/A-Scope/A-Scope.class";
5
- import { A_Feature } from "@adaas/a-concept/global/A-Feature/A-Feature.class";
6
4
  import { A_CommandContext } from "./context/A_Command.context";
7
- import { A_CONSTANTS__A_Command_Event, A_CONSTANTS__A_Command_Status, A_CONSTANTS_A_Command_Features } from "./A_Command.constants";
5
+ import { A_CONSTANTS__A_Command_Event, A_CONSTANTS__A_Command_Status } from "./A-Command.constants";
6
+ import { A_Context } from "../A-Context/A-Context.class";
7
+ import { A_CONSTANTS__DEFAULT_ENV_VARIABLES } from "@adaas/a-concept/constants/env.constants";
8
8
 
9
9
 
10
10
  export class A_Command<
11
11
  InvokeType extends A_TYPES__Command_Constructor = A_TYPES__Command_Constructor,
12
12
  ResultType extends Record<string, any> = Record<string, any>
13
- > extends A_Entity<
14
- InvokeType,
15
- A_TYPES__Command_Serialized<ResultType>
16
13
  > {
17
14
 
18
- protected _scope!: A_Scope;
15
+ // ====================================================================
16
+ // ================== Static A-Command Information ====================
17
+ // ====================================================================
18
+
19
+ /**
20
+ * Command Identifier that corresponds to the class name
21
+ */
22
+ static get code(): string {
23
+ return A_CommonHelper.toKebabCase(this.name);
24
+ }
25
+
26
+ /**
27
+ * DEFAULT Namespace of the command from environment variable A_CONCEPT_NAMESPACE
28
+ * [!] If environment variable is not set, it will default to 'a-concept'
29
+ */
30
+ static get namespace(): string {
31
+ return A_Context.root.name;
32
+ }
33
+
34
+ /**
35
+ * DEFAULT Scope of the command from environment variable A_CONCEPT_DEFAULT_SCOPE
36
+ * [!] If environment variable is not set, it will default to 'core'
37
+ * [!] Scope is an application specific identifier that can be used to group commands together
38
+ * [!] e.g. 'default', 'core', 'public', 'internal', etc
39
+ */
40
+ static get scope(): string {
41
+ return process && process.env ? process.env[A_CONSTANTS__DEFAULT_ENV_VARIABLES.A_CONCEPT_DEFAULT_SCOPE] || 'core' : 'core';
42
+ }
43
+
44
+ // ====================================================================
45
+ // ================ Instance A-Command Information ====================
46
+ // ====================================================================
47
+
48
+ /**
49
+ * ASEID is a command identifier that is unique across the system
50
+ * A - A_Concept or Application
51
+ * S - System or Scope
52
+ * E - Entity
53
+ * ID - Identifier
54
+ *
55
+ * [!] ASEID is immutable and should not be changed after the entity is created
56
+ *
57
+ * [!] ASEID is composed of the following parts:
58
+ * - namespace: an application specific identifier from where the command is coming from
59
+ * - scope: the scope of the command from Application Namespace
60
+ * - entity: the name of the command from Application Namespace
61
+ * - id: the unique identifier of the command
62
+ *
63
+ * [!] For more information about ASEID, please refer to the ASEID class documentation
64
+ */
65
+ aseid!: ASEID;
66
+
19
67
  protected _result?: ResultType;
20
68
  protected _errors?: Set<A_Error>;
21
69
 
@@ -45,7 +93,7 @@ export class A_Command<
45
93
  * Command execution context is stored in A_CommandContext fragment within this scope
46
94
  */
47
95
  get Scope(): A_Scope {
48
- return this._scope;
96
+ return A_Context.scope(this);
49
97
  }
50
98
 
51
99
  /**
@@ -54,7 +102,7 @@ export class A_Command<
54
102
  *
55
103
  */
56
104
  get Code(): string {
57
- return (this.constructor as typeof A_Command).name;
105
+ return (this.constructor as typeof A_Command).code;
58
106
  }
59
107
  /**
60
108
  * Current status of the command
@@ -111,7 +159,44 @@ export class A_Command<
111
159
  */
112
160
  params: InvokeType | A_TYPES__Command_Serialized<ResultType>
113
161
  ) {
114
- super(params as any);
162
+ if (params && typeof params === 'object' && 'aseid' in params) {
163
+ this.fromJSON(params);
164
+ } else {
165
+ this.fromNew(params);
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Extracts the ID from the ASEID
171
+ * ID is the unique identifier of the entity
172
+ */
173
+ get id(): string | number {
174
+ return this.aseid.id;
175
+ }
176
+
177
+ /**
178
+ * Extracts the namespace from the ASEID
179
+ * namespace is an application specific identifier from where the entity is coming from
180
+ */
181
+ get namespace(): string {
182
+ return this.aseid.namespace
183
+ }
184
+
185
+ /**
186
+ * Extracts the scope from the ASEID
187
+ * scope is the scope of the entity from Application Namespace
188
+ */
189
+ get scope(): string {
190
+ return this.aseid.scope;
191
+ }
192
+
193
+ /**
194
+ * Extracts the entity from the ASEID
195
+ * entity is the name of the entity from Application Namespace
196
+ *
197
+ */
198
+ get entity(): string {
199
+ return this.aseid.entity;
115
200
  }
116
201
 
117
202
 
@@ -123,13 +208,14 @@ export class A_Command<
123
208
  /**
124
209
  * Executes the command logic.
125
210
  */
126
- @A_Feature.Define()
127
- async [A_CONSTANTS_A_Command_Features.EXECUTE](): Promise<any> {
211
+ async execute(): Promise<any> {
128
212
  this._status = A_CONSTANTS__A_Command_Status.IN_PROGRESS;
129
213
  this._startTime = new Date();
214
+
130
215
  try {
131
- await this.call('execute', this._scope);
216
+ await this.call('execute');
132
217
  await this.complete();
218
+
133
219
  } catch (error) {
134
220
  await this.fail();
135
221
  }
@@ -138,26 +224,24 @@ export class A_Command<
138
224
  /**
139
225
  * Marks the command as completed
140
226
  */
141
- @A_Feature.Define()
142
- async [A_CONSTANTS_A_Command_Features.COMPLETE]() {
227
+ async complete() {
143
228
  this._status = A_CONSTANTS__A_Command_Status.COMPLETED;
144
229
  this._endTime = new Date();
145
230
  this._result = this.Scope.resolve(A_CommandContext).toJSON() as ResultType;
146
231
 
147
- this.call('complete', this._scope);
232
+ this.call('complete');
148
233
  }
149
234
 
150
235
 
151
236
  /**
152
237
  * Marks the command as failed
153
238
  */
154
- @A_Feature.Define()
155
- async [A_CONSTANTS_A_Command_Features.FAIL]() {
239
+ async fail() {
156
240
  this._status = A_CONSTANTS__A_Command_Status.FAILED;
157
241
  this._endTime = new Date();
158
242
  this._errors = this.Scope.resolve(A_CommandContext).Errors;
159
243
 
160
- this.call('fail', this._scope);
244
+ this.call('fail');
161
245
  }
162
246
 
163
247
 
@@ -211,19 +295,24 @@ export class A_Command<
211
295
  * @param newEntity
212
296
  */
213
297
  fromNew(newEntity: InvokeType): void {
214
- super.fromNew(newEntity);
215
298
 
299
+ this.aseid = new ASEID({
300
+ namespace: (this.constructor as typeof A_Command).namespace,
301
+ scope: (this.constructor as typeof A_Command).scope,
302
+ entity: (this.constructor as typeof A_Command).code,
303
+ id: `${new Date().getTime().toString()}-${Math.floor(Math.random() * 10000000).toString()}`,
304
+ });
216
305
 
217
- this._params = newEntity;
218
-
219
- this._status = A_CONSTANTS__A_Command_Status.INITIALIZED;
220
-
221
- this._scope = new A_Scope({
306
+ A_Context.allocate(this, {
222
307
  name: `a-command-scope::${this.id}`,
223
308
  fragments: [
224
309
  new A_CommandContext<ResultType>()
225
310
  ]
226
311
  });
312
+
313
+ this._params = newEntity;
314
+
315
+ this._status = A_CONSTANTS__A_Command_Status.INITIALIZED;
227
316
  }
228
317
 
229
318
 
@@ -236,19 +325,21 @@ export class A_Command<
236
325
  * @param serialized
237
326
  */
238
327
  fromJSON(serialized: A_TYPES__Command_Serialized<ResultType>): void {
239
- super.fromJSON(serialized);
240
- if (serialized.startedAt) this._startTime = new Date(serialized.startedAt);
241
- if (serialized.endedAt) this._endTime = new Date(serialized.endedAt);
242
-
243
-
328
+ this.aseid = new ASEID(serialized.aseid);
244
329
  const context = new A_CommandContext<ResultType>();
245
330
 
246
- this._scope = new A_Scope({
331
+ A_Context.allocate(this, {
247
332
  name: `a-command-scope::${this.id}`,
248
333
  fragments: [
249
334
  context
250
335
  ]
251
- })
336
+ });
337
+
338
+ if (serialized.startedAt) this._startTime = new Date(serialized.startedAt);
339
+ if (serialized.endedAt) this._endTime = new Date(serialized.endedAt);
340
+
341
+
342
+
252
343
  // Restore result and errors in the context
253
344
  if (serialized.result) {
254
345
  Object.entries(serialized.result).forEach(([key, value]) => {
@@ -273,7 +364,7 @@ export class A_Command<
273
364
  */
274
365
  toJSON(): A_TYPES__Command_Serialized<ResultType> {
275
366
  return {
276
- ...super.toJSON(),
367
+ aseid: this.aseid.toString(),
277
368
  code: this.Code,
278
369
  status: this._status,
279
370
  startedAt: this._startTime ? this._startTime.toISOString() : undefined,
@@ -284,4 +375,27 @@ export class A_Command<
284
375
  }
285
376
  };
286
377
 
378
+
379
+
380
+ /**
381
+ * Call a feature of the component with the provided scope
382
+ *
383
+ * [!] If the provided scope is not inherited from the entity scope, it will be inherited
384
+ *
385
+ * @param lifecycleMethod
386
+ * @param args
387
+ */
388
+ async call(
389
+ feature: string,
390
+ scope: A_Scope = this.Scope
391
+ ) {
392
+ if (scope && !scope.isInheritedFrom(this.Scope)) {
393
+ scope = scope.inherit(this.Scope);
394
+ }
395
+
396
+ const newFeature = A_Context.feature(this, feature, scope);
397
+
398
+ return await newFeature.process();
399
+ }
400
+
287
401
  }
@@ -0,0 +1,22 @@
1
+ import { A_Meta } from "../A-Meta/A-Meta.class";
2
+ import { A_TYPES__CommandMeta, A_TYPES__CommandMetaKey } from "./A-Command.types";
3
+ import { A_TYPES__A_DefineDecorator_Meta } from "@adaas/a-concept/decorators/A-Feature/A-Feature.decorator.types";
4
+
5
+
6
+ export class A_CommandMeta extends A_Meta<A_TYPES__CommandMeta> {
7
+
8
+ /**
9
+ * Returns all features defined in the Container
10
+ *
11
+ * @returns
12
+ */
13
+ features(): Array<A_TYPES__A_DefineDecorator_Meta> {
14
+
15
+ const features = this.get(A_TYPES__CommandMetaKey.FEATURES);
16
+
17
+ return features?.toArray()
18
+ // returns all extensions that match the feature
19
+ .map(([, feature]) => feature) || [];
20
+ }
21
+
22
+ }
@@ -0,0 +1,71 @@
1
+ import { A_Command } from "./A-Command.class";
2
+ import { A_CONSTANTS__A_Command_Status } from "./A-Command.constants";
3
+ import { A_TYPES__Error } from "@adaas/a-utils";
4
+ import { A_Meta } from "../A-Meta/A-Meta.class";
5
+ import { A_TYPES__A_DefineDecorator_Meta, A_TYPES__A_ExtendDecorator_Meta } from "@adaas/a-concept/decorators/A-Feature/A-Feature.decorator.types";
6
+
7
+
8
+
9
+ export type A_TYPES__Command_Constructor = {
10
+ }
11
+
12
+
13
+
14
+ export type A_TYPES__Command_Serialized<
15
+ ResultType extends Record<string, any> = Record<string, any>
16
+ > = {
17
+ aseid: string,
18
+ code: string;
19
+ status: A_CONSTANTS__A_Command_Status;
20
+
21
+ startedAt?: string;
22
+ endedAt?: string;
23
+ duration?: number;
24
+
25
+ result?: ResultType;
26
+ errors?: Array<A_TYPES__Error>;
27
+
28
+ }
29
+
30
+
31
+
32
+
33
+ export type A_TYPES__Command_Listener<
34
+ T extends Record<string, any> = Record<string, any>
35
+ > = (command?: A_Command<any, T>) => void;
36
+
37
+
38
+
39
+
40
+
41
+
42
+ export type A_TYPES__CommandMeta = {
43
+ [A_TYPES__CommandMetaKey.EXTENSIONS]: A_Meta<{
44
+
45
+ /**
46
+ * Where Key the regexp for what to apply the extension
47
+ * A set of container names or a wildcard, or a regexp
48
+ *
49
+ *
50
+ * Where value is the extension instructions
51
+ */
52
+ [Key: string]: A_TYPES__A_ExtendDecorator_Meta[]
53
+
54
+ }>, case
55
+
56
+
57
+ [A_TYPES__CommandMetaKey.FEATURES]: A_Meta<{
58
+ /**
59
+ * Where Key is the name of the feature
60
+ *
61
+ * Where value is the list of features
62
+ */
63
+ [Key: string]: A_TYPES__A_DefineDecorator_Meta
64
+ }>
65
+ }
66
+
67
+ export enum A_TYPES__CommandMetaKey {
68
+ EXTENSIONS = 'a-command-extensions',
69
+ FEATURES = 'a-command-features',
70
+ ABSTRACTIONS = 'a-command-abstractions',
71
+ }
@@ -106,6 +106,9 @@ export class A_Concept<
106
106
  if (props.entities && props.entities.length)
107
107
  props.entities.forEach(entity => this.Scope.register(entity))
108
108
 
109
+ if (props.commands && props.commands.length)
110
+ props.commands.forEach(command => this.Scope.register(command))
111
+
109
112
  this.containers = props.containers || [];
110
113
  }
111
114
 
@@ -4,6 +4,7 @@ import { A_Fragment } from "../A-Fragment/A-Fragment.class";
4
4
  import { A_Entity } from "../A-Entity/A-Entity.class";
5
5
  import { A_Component } from "../A-Component/A-Component.class";
6
6
  import { A_TYPES__A_ExtendDecorator_BehaviorConfig } from "@adaas/a-concept/decorators/A-Feature/A-Feature.decorator.types";
7
+ import { A_Command } from "../A-Command/A-Command.class";
7
8
 
8
9
 
9
10
  export enum A_TYPES__ConceptStage {
@@ -68,6 +69,15 @@ export interface A_TYPES__IConceptConstructor<
68
69
  * [!] Note that these components will be available in all containers and fragments in the concept.
69
70
  */
70
71
  components?: Array<{ new(...args: any[]): A_Component }>
72
+
73
+
74
+ /**
75
+ * A set of Commands available for all containers and fragments in the concept.
76
+ * These commands will be registered in the root scope of the concept.
77
+ *
78
+ * [!] Note that these commands will be available in all containers and fragments in the concept.
79
+ */
80
+ commands?: Array<{ new(...args: any[]): A_Command }>
71
81
  }
72
82
 
73
83
 
@@ -22,6 +22,8 @@ import { A_TYPES__ComponentMetaKey } from "../A-Component/A-Component.types";
22
22
  import { A_TYPES__ConceptStage } from "../A-Concept/A_Concept.types";
23
23
  import { A_TYPES__A_DefineDecorator_Meta } from "@adaas/a-concept/decorators/A-Feature/A-Feature.decorator.types";
24
24
  import { A_CONSTANTS__DEFAULT_ENV_VARIABLES } from "@adaas/a-concept/constants/env.constants";
25
+ import { A_Command } from "../A-Command/A-Command.class";
26
+ import { A_TYPES__CommandMetaKey } from "../A-Command/A-Command.types";
25
27
 
26
28
 
27
29
 
@@ -47,6 +49,9 @@ export class A_Context {
47
49
  protected features: WeakMap<A_Feature, A_Scope> = new WeakMap();
48
50
 
49
51
 
52
+ protected commands: WeakMap<A_Command, A_Scope> = new WeakMap();
53
+
54
+
50
55
  /**
51
56
  * Uses to store the scope of every element in the program.
52
57
  */
@@ -164,6 +169,11 @@ export class A_Context {
164
169
 
165
170
  break;
166
171
 
172
+ case param1 instanceof A_Command:
173
+ instance.commands.set(param1, newScope);
174
+
175
+ break;
176
+
167
177
  default:
168
178
  throw new Error(`[!] A-Concept Context: Unknown type of the parameter.`);
169
179
  }
@@ -356,6 +366,9 @@ export class A_Context {
356
366
  case param1 instanceof A_Fragment:
357
367
  return instance.registry.get(param1);
358
368
 
369
+ case param1 instanceof A_Command:
370
+ return instance.commands.get(param1);
371
+
359
372
  default:
360
373
  throw new Error(`[!] A-Concept Context: Unknown type of the parameter.`);
361
374
  }
@@ -444,10 +457,13 @@ export class A_Context {
444
457
  case component instanceof A_Container:
445
458
  metaKey = A_TYPES__ContainerMetaKey.FEATURES
446
459
  break;
447
- case component instanceof A_Component: {
460
+ case component instanceof A_Component:
448
461
  metaKey = A_TYPES__ComponentMetaKey.FEATURES
449
- }
450
462
  break;
463
+ case component instanceof A_Command:
464
+ metaKey = A_TYPES__CommandMetaKey.FEATURES
465
+ break;
466
+
451
467
  default:
452
468
  throw new Error(`A-Feature cannot be defined on the ${component} level`);
453
469
  }
@@ -499,7 +515,7 @@ export class A_Context {
499
515
  * @returns
500
516
  */
501
517
  static abstractionDefinition(
502
- component: A_Component | A_Container | A_Entity,
518
+ component: A_Component | A_Container | A_Entity | A_Command,
503
519
  abstraction: A_TYPES__ConceptStage,
504
520
  scope: A_Scope
505
521
  ): A_TYPES__FeatureConstructor {
@@ -516,9 +532,11 @@ export class A_Context {
516
532
  case component instanceof A_Container:
517
533
  metaKey = A_TYPES__ContainerMetaKey.ABSTRACTIONS
518
534
  break;
519
- case component instanceof A_Component: {
535
+ case component instanceof A_Component:
520
536
  metaKey = A_TYPES__ComponentMetaKey.ABSTRACTIONS
521
- }
537
+ break;
538
+ case component instanceof A_Command:
539
+ metaKey = A_TYPES__CommandMetaKey.ABSTRACTIONS
522
540
  break;
523
541
  default:
524
542
  throw new Error(`A-Feature cannot be defined on the ${component} level`);
@@ -36,10 +36,7 @@ export class A_Entity<
36
36
  * Entity Identifier that corresponds to the class name
37
37
  */
38
38
  static get entity(): string {
39
- return A_CommonHelper
40
- .toUpperSnakeCase(this.name)
41
- .toLocaleLowerCase()
42
- .replace(/_/g, '-');
39
+ return A_CommonHelper.toKebabCase(this.name);
43
40
  }
44
41
 
45
42
  /**
@@ -1,3 +1,4 @@
1
+ import { A_Command } from "../A-Command/A-Command.class";
1
2
  import { A_Component } from "../A-Component/A-Component.class";
2
3
  import { A_Container } from "../A-Container/A-Container.class";
3
4
  import { A_Feature } from "./A-Feature.class";
@@ -15,10 +16,10 @@ import { A_Feature } from "./A-Feature.class";
15
16
  export class A_FeatureCaller {
16
17
 
17
18
 
18
- protected _component: A_Component | A_Feature | A_Container;
19
+ protected _component: A_Component | A_Feature | A_Container | A_Command;
19
20
 
20
21
  constructor(
21
- component: A_Component | A_Feature | A_Container
22
+ component: A_Component | A_Feature | A_Container | A_Command
22
23
  ) {
23
24
  this._component = component;
24
25
  }
@@ -29,7 +30,7 @@ export class A_FeatureCaller {
29
30
  *
30
31
  * @returns
31
32
  */
32
- resolve(): A_Component | A_Feature | A_Container {
33
+ resolve(): A_Component | A_Feature | A_Container | A_Command {
33
34
  return this._component;
34
35
  }
35
36