@adaas/a-concept 0.0.60 → 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.
- package/dist/index.d.ts +4 -4
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/src/decorators/A-Feature/A-Feature-Define.decorator.d.ts +2 -1
- package/dist/src/decorators/A-Feature/A-Feature-Define.decorator.js +9 -2
- package/dist/src/decorators/A-Feature/A-Feature-Define.decorator.js.map +1 -1
- package/dist/src/{base/A-Command/A_Command.entity.d.ts → global/A-Command/A-Command.class.d.ts} +72 -10
- package/dist/src/{base/A-Command/A_Command.entity.js → global/A-Command/A-Command.class.js} +119 -46
- package/dist/src/global/A-Command/A-Command.class.js.map +1 -0
- package/dist/src/{base/A-Command/A_Command.constants.js → global/A-Command/A-Command.constants.js} +1 -1
- package/dist/src/global/A-Command/A-Command.constants.js.map +1 -0
- package/dist/src/global/A-Command/A-Command.meta.d.ts +11 -0
- package/dist/src/global/A-Command/A-Command.meta.js +18 -0
- package/dist/src/global/A-Command/A-Command.meta.js.map +1 -0
- package/dist/src/global/A-Command/A-Command.types.d.ts +43 -0
- package/dist/src/global/A-Command/A-Command.types.js +10 -0
- package/dist/src/global/A-Command/A-Command.types.js.map +1 -0
- package/dist/src/{base → global}/A-Command/context/A_Command.context.d.ts +1 -1
- package/dist/src/{base → global}/A-Command/context/A_Command.context.js +1 -1
- package/dist/src/global/A-Command/context/A_Command.context.js.map +1 -0
- package/dist/src/global/A-Concept/A_Concept.class.js +2 -0
- package/dist/src/global/A-Concept/A_Concept.class.js.map +1 -1
- package/dist/src/global/A-Concept/A_Concept.types.d.ts +10 -0
- package/dist/src/global/A-Concept/A_Concept.types.js.map +1 -1
- package/dist/src/global/A-Context/A-Context.class.d.ts +3 -1
- package/dist/src/global/A-Context/A-Context.class.js +16 -6
- package/dist/src/global/A-Context/A-Context.class.js.map +1 -1
- package/dist/src/global/A-Entity/A-Entity.class.js +1 -4
- package/dist/src/global/A-Entity/A-Entity.class.js.map +1 -1
- package/dist/src/global/A-Feature/A-FeatureCaller.class.d.ts +4 -3
- package/dist/src/global/A-Feature/A-FeatureCaller.class.js.map +1 -1
- package/dist/src/global/A-Scope/A-Scope.class.d.ts +15 -1
- package/dist/src/global/A-Scope/A-Scope.class.js +62 -5
- package/dist/src/global/A-Scope/A-Scope.class.js.map +1 -1
- package/dist/src/global/A-Scope/A-Scope.types.d.ts +7 -0
- package/dist/src/global/A-Stage/A-Stage.class.d.ts +1 -1
- package/index.ts +4 -4
- package/package.json +2 -2
- package/src/decorators/A-Feature/A-Feature-Define.decorator.ts +13 -6
- package/src/{base/A-Command/A_Command.entity.ts → global/A-Command/A-Command.class.ts} +149 -35
- package/src/global/A-Command/A-Command.meta.ts +22 -0
- package/src/global/A-Command/A-Command.types.ts +71 -0
- package/src/global/A-Concept/A_Concept.class.ts +3 -0
- package/src/global/A-Concept/A_Concept.types.ts +10 -0
- package/src/global/A-Context/A-Context.class.ts +23 -5
- package/src/global/A-Entity/A-Entity.class.ts +1 -4
- package/src/global/A-Feature/A-FeatureCaller.class.ts +4 -3
- package/src/global/A-Scope/A-Scope.class.ts +81 -9
- package/src/global/A-Scope/A-Scope.types.ts +7 -0
- package/tests/A-Command.test.ts +15 -11
- package/tests/A-Concept.test.ts +110 -0
- package/tests/A-Scope.test.ts +45 -4
- package/dist/src/base/A-Command/A_Command.constants.js.map +0 -1
- package/dist/src/base/A-Command/A_Command.entity.js.map +0 -1
- package/dist/src/base/A-Command/A_Command.types.d.ts +0 -15
- package/dist/src/base/A-Command/A_Command.types.js +0 -3
- package/dist/src/base/A-Command/A_Command.types.js.map +0 -1
- package/dist/src/base/A-Command/context/A_Command.context.js.map +0 -1
- package/src/base/A-Command/A_Command.types.ts +0 -34
- /package/dist/src/{base/A-Command/A_Command.constants.d.ts → global/A-Command/A-Command.constants.d.ts} +0 -0
- /package/src/{base/A-Command/A_Command.constants.ts → global/A-Command/A-Command.constants.ts} +0 -0
- /package/src/{base → global}/A-Command/context/A_Command.context.ts +0 -0
|
@@ -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
|
-
|
|
56
|
-
|
|
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 {
|
|
2
|
-
import {
|
|
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
|
|
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
|
-
|
|
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
|
|
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).
|
|
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
|
-
|
|
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
|
-
|
|
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'
|
|
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
|
-
|
|
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'
|
|
232
|
+
this.call('complete');
|
|
148
233
|
}
|
|
149
234
|
|
|
150
235
|
|
|
151
236
|
/**
|
|
152
237
|
* Marks the command as failed
|
|
153
238
|
*/
|
|
154
|
-
|
|
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'
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|