@adaas/a-concept 0.0.55 → 0.0.57
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/.nvmrc +1 -1
- package/dist/src/base/A-Command/A_Command.constants.d.ts +12 -0
- package/dist/src/base/A-Command/A_Command.constants.js +17 -0
- package/dist/src/base/A-Command/A_Command.constants.js.map +1 -0
- package/dist/src/base/A-Command/A_Command.entity.d.ts +123 -0
- package/dist/src/base/A-Command/A_Command.entity.js +259 -0
- package/dist/src/base/A-Command/A_Command.entity.js.map +1 -0
- package/dist/src/base/A-Command/A_Command.types.d.ts +15 -0
- package/dist/src/base/A-Command/A_Command.types.js +3 -0
- package/dist/src/base/A-Command/A_Command.types.js.map +1 -0
- package/dist/src/base/A-Command/context/A_Command.context.d.ts +64 -0
- package/dist/src/base/A-Command/context/A_Command.context.js +85 -0
- package/dist/src/base/A-Command/context/A_Command.context.js.map +1 -0
- package/dist/src/base/A-Command/context/A_CommandFactory.context.js +2 -0
- package/dist/src/base/A-Command/context/A_CommandFactory.context.js.map +1 -0
- package/dist/src/base/A-Config/A-Config.context.d.ts +7 -6
- package/dist/src/base/A-Config/A-Config.context.js +2 -6
- package/dist/src/base/A-Config/A-Config.context.js.map +1 -1
- package/dist/src/base/A-Config/components/ConfigReader.component.js +2 -12
- package/dist/src/base/A-Config/components/ConfigReader.component.js.map +1 -1
- package/dist/src/constants/env.constants.d.ts +26 -0
- package/dist/src/constants/env.constants.js +40 -0
- package/dist/src/constants/env.constants.js.map +1 -0
- package/dist/src/decorators/A-Inject/A-Inject.decorator.d.ts +3 -3
- package/dist/src/decorators/A-Inject/A-Inject.decorator.types.d.ts +9 -10
- package/dist/src/global/A-Channel/A-Channel.class.d.ts +2 -0
- package/dist/src/global/A-Channel/A-Channel.class.js +2 -0
- package/dist/src/global/A-Channel/A-Channel.class.js.map +1 -1
- package/dist/src/global/A-Concept/A_Concept.class.d.ts +5 -3
- package/dist/src/global/A-Concept/A_Concept.class.js +32 -27
- package/dist/src/global/A-Concept/A_Concept.class.js.map +1 -1
- package/dist/src/global/A-Concept/A_Concept.meta.d.ts +1 -8
- package/dist/src/global/A-Concept/A_Concept.meta.js +1 -25
- package/dist/src/global/A-Concept/A_Concept.meta.js.map +1 -1
- package/dist/src/global/A-Concept/A_Concept.types.d.ts +10 -1
- package/dist/src/global/A-Container/A-Container.class.d.ts +5 -0
- package/dist/src/global/A-Container/A-Container.class.js +5 -0
- package/dist/src/global/A-Container/A-Container.class.js.map +1 -1
- package/dist/src/global/A-Context/A-Context.class.d.ts +19 -1
- package/dist/src/global/A-Context/A-Context.class.js +20 -0
- package/dist/src/global/A-Context/A-Context.class.js.map +1 -1
- package/dist/src/global/A-Entity/A-Entity.class.d.ts +124 -23
- package/dist/src/global/A-Entity/A-Entity.class.js +159 -49
- package/dist/src/global/A-Entity/A-Entity.class.js.map +1 -1
- package/dist/src/global/A-Scope/A-Scope.class.d.ts +7 -6
- package/dist/src/global/A-Scope/A-Scope.class.js +57 -21
- package/dist/src/global/A-Scope/A-Scope.class.js.map +1 -1
- package/dist/src/global/A-Stage/A-Stage.class.d.ts +3 -2
- package/dist/src/global/A-Stage/A-Stage.class.js +9 -6
- package/dist/src/global/A-Stage/A-Stage.class.js.map +1 -1
- package/dist/src/global/A-Stage/A-Stage.types.d.ts +1 -1
- package/dist/src/helpers/StepsManager.class.js +1 -1
- package/dist/src/helpers/StepsManager.class.js.map +1 -1
- package/examples/simple/components/A.component.ts +9 -2
- package/examples/simple/concept.ts +6 -0
- package/examples/simple/entities/EntityA.entity.ts +18 -0
- package/jest.config.ts +1 -1
- package/package.json +3 -3
- package/src/base/A-Command/A_Command.constants.ts +20 -0
- package/src/base/A-Command/A_Command.entity.ts +287 -0
- package/src/base/A-Command/A_Command.types.ts +34 -0
- package/src/base/A-Command/context/A_Command.context.ts +114 -0
- package/src/base/A-Command/context/A_CommandFactory.context.ts +0 -0
- package/src/base/A-Config/A-Config.context.ts +13 -17
- package/src/base/A-Config/components/ConfigReader.component.ts +2 -15
- package/src/constants/env.constants.ts +47 -0
- package/src/decorators/A-Inject/A-Inject.decorator.ts +3 -3
- package/src/decorators/A-Inject/A-Inject.decorator.types.ts +10 -9
- package/src/global/A-Channel/A-Channel.class.ts +2 -0
- package/src/global/A-Concept/A_Concept.class.ts +49 -32
- package/src/global/A-Concept/A_Concept.meta.ts +3 -41
- package/src/global/A-Concept/A_Concept.types.ts +6 -4
- package/src/global/A-Container/A-Container.class.ts +5 -2
- package/src/global/A-Context/A-Context.class.ts +44 -7
- package/src/global/A-Entity/A-Entity.class.ts +203 -73
- package/src/global/A-Scope/A-Scope.class.ts +86 -43
- package/src/global/A-Stage/A-Stage.class.ts +11 -7
- package/src/global/A-Stage/A-Stage.types.ts +1 -1
- package/src/helpers/StepsManager.class.ts +2 -2
- package/tests/A-Command.test.ts +130 -0
- package/tests/A-Component.test.ts +25 -0
- package/tests/A-Entity.test.ts +186 -0
- package/tests/A-Feature.test.ts +131 -0
- package/tests/A-Scope.test.ts +163 -0
- package/dist/src/constants/A_ConceptLifecycle.constants.js +0 -11
- package/dist/src/constants/A_ConceptLifecycle.constants.js.map +0 -1
- package/src/constants/A_ConceptLifecycle.constants.ts +0 -12
- package/tests/channel.ts +0 -213
- package/tests/context.test.ts +0 -124
- package/tests/default.test.ts +0 -159
- package/tests/log.ts +0 -102
- package/tests/polyfill.test.ts +0 -37
- /package/dist/src/{constants/A_ConceptLifecycle.constants.d.ts → base/A-Command/context/A_CommandFactory.context.d.ts} +0 -0
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
} from "./A-Entity.types";
|
|
10
10
|
import { A_CONSTANTS__DEFAULT_ERRORS } from "@adaas/a-utils/dist/src/constants/errors.constants";
|
|
11
11
|
import { A_Context } from "../A-Context/A-Context.class";
|
|
12
|
-
import { A_TYPES__FeatureCallParams } from "../A-Feature/A-Feature.types";
|
|
13
12
|
import { A_Scope } from "../A-Scope/A-Scope.class";
|
|
13
|
+
import { A_CONSTANTS__DEFAULT_ENV_VARIABLES, A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY } from "@adaas/a-concept/constants/env.constants";
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
@@ -27,8 +27,10 @@ export class A_Entity<
|
|
|
27
27
|
>
|
|
28
28
|
implements A_TYPES__IEntity {
|
|
29
29
|
|
|
30
|
-
aseid!: ASEID;
|
|
31
30
|
|
|
31
|
+
// ====================================================================
|
|
32
|
+
// ================== Static A-Entity Information ============================
|
|
33
|
+
// ====================================================================
|
|
32
34
|
|
|
33
35
|
/**
|
|
34
36
|
* Entity Identifier that corresponds to the class name
|
|
@@ -40,6 +42,49 @@ export class A_Entity<
|
|
|
40
42
|
.replace(/_/g, '-');
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
/**
|
|
46
|
+
* DEFAULT Namespace of the entity from environment variable A_CONCEPT_NAMESPACE
|
|
47
|
+
* [!] If environment variable is not set, it will default to 'a-concept'
|
|
48
|
+
*/
|
|
49
|
+
static get namespace(): string {
|
|
50
|
+
return process && process.env ? process.env[A_CONSTANTS__DEFAULT_ENV_VARIABLES.A_CONCEPT_NAMESPACE] || 'a-concept' : 'a-concept';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* DEFAULT Scope of the entity from environment variable A_CONCEPT_DEFAULT_SCOPE
|
|
55
|
+
* [!] If environment variable is not set, it will default to 'core'
|
|
56
|
+
* [!] Scope is an application specific identifier that can be used to group entities together
|
|
57
|
+
* [!] e.g. 'default', 'core', 'public', 'internal', etc
|
|
58
|
+
*/
|
|
59
|
+
static get scope(): string {
|
|
60
|
+
return process && process.env ? process.env[A_CONSTANTS__DEFAULT_ENV_VARIABLES.A_CONCEPT_DEFAULT_SCOPE] || 'core' : 'core';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ====================================================================
|
|
64
|
+
// ================== Instance A-Entity Information ====================
|
|
65
|
+
// ====================================================================
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* ASEID is an entity identifier that is unique across the system
|
|
69
|
+
* A - A_Concept or Application
|
|
70
|
+
* S - System or Scope
|
|
71
|
+
* E - Entity
|
|
72
|
+
* ID - Identifier
|
|
73
|
+
*
|
|
74
|
+
* [!] ASEID is immutable and should not be changed after the entity is created
|
|
75
|
+
*
|
|
76
|
+
* [!] ASEID is composed of the following parts:
|
|
77
|
+
* - namespace: an application specific identifier from where the entity is coming from
|
|
78
|
+
* - scope: the scope of the entity from Application Namespace
|
|
79
|
+
* - entity: the name of the entity from Application Namespace
|
|
80
|
+
* - id: the unique identifier of the entity
|
|
81
|
+
*
|
|
82
|
+
* [!] For more information about ASEID, please refer to the ASEID class documentation]
|
|
83
|
+
*/
|
|
84
|
+
aseid!: ASEID;
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
43
88
|
/**
|
|
44
89
|
* Create a new A_entity instance from Aseid String
|
|
45
90
|
* e.g. project@scope:entity:0000000001
|
|
@@ -50,7 +95,7 @@ export class A_Entity<
|
|
|
50
95
|
/**
|
|
51
96
|
* ASEID string that represents the entity
|
|
52
97
|
*/
|
|
53
|
-
aseid
|
|
98
|
+
aseid?: string
|
|
54
99
|
)
|
|
55
100
|
/**
|
|
56
101
|
* Create a new A_entity instance from Aseid instance
|
|
@@ -84,15 +129,72 @@ export class A_Entity<
|
|
|
84
129
|
/**
|
|
85
130
|
* Constructor object that represents the entity
|
|
86
131
|
*/
|
|
87
|
-
newEntity
|
|
132
|
+
newEntity?: _ConstructorType
|
|
88
133
|
)
|
|
89
|
-
constructor(props
|
|
134
|
+
constructor(props?: string | ASEID | _SerializedType | _ConstructorType) {
|
|
90
135
|
|
|
91
136
|
const initializer = this.getInitializer(props);
|
|
92
137
|
// the returned initializer is already bound to `this` (we used .bind(this)),
|
|
93
138
|
// so calling it will run the appropriate logic on this instance:
|
|
94
139
|
initializer.call(this, props);
|
|
95
140
|
}
|
|
141
|
+
// ====================================================================
|
|
142
|
+
// ================== DUPLICATED ASEID Getters ========================
|
|
143
|
+
// ====================================================================
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Extracts the ID from the ASEID
|
|
147
|
+
* ID is the unique identifier of the entity
|
|
148
|
+
*/
|
|
149
|
+
get id(): string | number {
|
|
150
|
+
return this.aseid.id;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Extracts the namespace from the ASEID
|
|
155
|
+
* namespace is an application specific identifier from where the entity is coming from
|
|
156
|
+
*/
|
|
157
|
+
get namespace(): string {
|
|
158
|
+
return this.aseid.namespace
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Extracts the scope from the ASEID
|
|
163
|
+
* scope is the scope of the entity from Application Namespace
|
|
164
|
+
*/
|
|
165
|
+
get scope(): string {
|
|
166
|
+
return this.aseid.scope;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Extracts the entity from the ASEID
|
|
171
|
+
* entity is the name of the entity from Application Namespace
|
|
172
|
+
*
|
|
173
|
+
*/
|
|
174
|
+
get entity(): string {
|
|
175
|
+
return this.aseid.entity;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Extracts the version from the ASEID
|
|
180
|
+
* version is the version of the entity
|
|
181
|
+
*/
|
|
182
|
+
|
|
183
|
+
get version(): string | undefined {
|
|
184
|
+
return this.aseid.version;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Extracts the shard from the ASEID
|
|
189
|
+
* shard is the shard of the entity
|
|
190
|
+
*/
|
|
191
|
+
get shard(): string | undefined {
|
|
192
|
+
return this.aseid.shard;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ====================================================================
|
|
196
|
+
// ================== Constructor Helpers =============================
|
|
197
|
+
// ====================================================================
|
|
96
198
|
|
|
97
199
|
|
|
98
200
|
// --- Type guards used to classify `props` properly ---
|
|
@@ -126,10 +228,42 @@ export class A_Entity<
|
|
|
126
228
|
return !!x && typeof x === "object" && !("aseid" in (x as object));
|
|
127
229
|
}
|
|
128
230
|
|
|
129
|
-
|
|
231
|
+
/**
|
|
232
|
+
* Determines the appropriate initializer method based on the type of `props`.
|
|
233
|
+
* The method checks if `props` is:
|
|
234
|
+
* 1) a string that matches ASEID format -> fromASEID
|
|
235
|
+
* 2) an ASEID instance -> fromASEID
|
|
236
|
+
* 3) a serialized object (has 'aseid') -> fromJSON
|
|
237
|
+
* 4) a plain object with no 'aseid' -> treat as constructor props -> fromNew
|
|
238
|
+
*
|
|
239
|
+
* [!] If `props` is undefined, it will call fromUndefined method
|
|
240
|
+
*
|
|
241
|
+
* If none of the above, it throws an error indicating incorrect constructor usage.
|
|
242
|
+
*
|
|
243
|
+
*
|
|
244
|
+
* To get a custom initializer, override this method in the child class.
|
|
245
|
+
* Example:
|
|
246
|
+
* ```typescript
|
|
247
|
+
* protected getInitializer(
|
|
248
|
+
* props?: string | ASEID | _SerializedType | _ConstructorType
|
|
249
|
+
* ): (props: any) => void | (() => void) {
|
|
250
|
+
* if('customField' in props) {
|
|
251
|
+
* return this.fromCustomField.bind(this);
|
|
252
|
+
* }
|
|
253
|
+
* return super.getInitializer(props);
|
|
254
|
+
* }
|
|
255
|
+
* ```
|
|
256
|
+
* @param props
|
|
257
|
+
* @returns The appropriate initializer method
|
|
258
|
+
*/
|
|
130
259
|
protected getInitializer(
|
|
131
|
-
props
|
|
132
|
-
): (props: any) => void {
|
|
260
|
+
props?: string | ASEID | _SerializedType | _ConstructorType
|
|
261
|
+
): (props: any) => void | (() => void) {
|
|
262
|
+
|
|
263
|
+
if (!props) {
|
|
264
|
+
return this.fromUndefined
|
|
265
|
+
}
|
|
266
|
+
|
|
133
267
|
// 1) string that matches ASEID format -> fromASEID
|
|
134
268
|
if (this.isStringASEID(props)) {
|
|
135
269
|
return this.fromASEID as (p: string) => void;
|
|
@@ -155,67 +289,10 @@ export class A_Entity<
|
|
|
155
289
|
}
|
|
156
290
|
|
|
157
291
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
// ====================================================================
|
|
161
|
-
// ================== DUPLICATED ASEID Getters ========================
|
|
162
|
-
// ====================================================================
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Extracts the ID from the ASEID
|
|
166
|
-
* ID is the unique identifier of the entity
|
|
167
|
-
*/
|
|
168
|
-
get id(): string | number {
|
|
169
|
-
return this.aseid.id;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Extracts the namespace from the ASEID
|
|
174
|
-
* namespace is an application specific identifier from where the entity is coming from
|
|
175
|
-
*/
|
|
176
|
-
get namespace(): string {
|
|
177
|
-
return this.aseid.namespace
|
|
178
|
-
}
|
|
179
|
-
|
|
180
292
|
/**
|
|
181
|
-
*
|
|
182
|
-
* scope is the scope of the entity from Application Namespace
|
|
183
|
-
*/
|
|
184
|
-
get scope(): string {
|
|
185
|
-
return this.aseid.scope;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Extracts the entity from the ASEID
|
|
190
|
-
* entity is the name of the entity from Application Namespace
|
|
293
|
+
* Call a feature of the component with the provided scope
|
|
191
294
|
*
|
|
192
|
-
|
|
193
|
-
get entity(): string {
|
|
194
|
-
return this.aseid.entity;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Extracts the version from the ASEID
|
|
199
|
-
* version is the version of the entity
|
|
200
|
-
*/
|
|
201
|
-
|
|
202
|
-
get version(): string | undefined {
|
|
203
|
-
return this.aseid.version;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Extracts the shard from the ASEID
|
|
208
|
-
* shard is the shard of the entity
|
|
209
|
-
*/
|
|
210
|
-
get shard(): string | undefined {
|
|
211
|
-
return this.aseid.shard;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Call a feature of the component
|
|
295
|
+
* [!] If the provided scope is not inherited from the entity scope, it will be inherited
|
|
219
296
|
*
|
|
220
297
|
* @param lifecycleMethod
|
|
221
298
|
* @param args
|
|
@@ -228,8 +305,6 @@ export class A_Entity<
|
|
|
228
305
|
// or it can be inherited from the entity scope
|
|
229
306
|
// [!Not Now!] however, each feature should create own scope regardless of the passed scope
|
|
230
307
|
// to avoid any possible side effects
|
|
231
|
-
|
|
232
|
-
|
|
233
308
|
if (scope && !scope.isInheritedFrom(A_Context.scope(this))) {
|
|
234
309
|
scope = scope.inherit(A_Context.scope(this));
|
|
235
310
|
}
|
|
@@ -244,8 +319,6 @@ export class A_Entity<
|
|
|
244
319
|
// ================== Entity Base Methods =============================
|
|
245
320
|
// ====================================================================
|
|
246
321
|
|
|
247
|
-
|
|
248
|
-
|
|
249
322
|
/**
|
|
250
323
|
* The default method that can be called and extended to load entity data.
|
|
251
324
|
*/
|
|
@@ -275,6 +348,13 @@ export class A_Entity<
|
|
|
275
348
|
// ================== Entity Serialization ============================
|
|
276
349
|
// ====================================================================
|
|
277
350
|
|
|
351
|
+
/**
|
|
352
|
+
* Create a new entity from ASEID string or instance
|
|
353
|
+
* [!] Executed when the constructor is called with a string or ASEID instance that represents the ASEID
|
|
354
|
+
* [!] Executes By Default with new A_Entity('aseid-string') or new A_Entity(new ASEID(...)) if getInitializer has not been overridden
|
|
355
|
+
*
|
|
356
|
+
* @param aseid
|
|
357
|
+
*/
|
|
278
358
|
fromASEID(aseid: string | ASEID): void {
|
|
279
359
|
if (typeof aseid === 'string' && ASEID.isASEID(aseid)) {
|
|
280
360
|
this.aseid = new ASEID(aseid);
|
|
@@ -285,14 +365,56 @@ export class A_Entity<
|
|
|
285
365
|
}
|
|
286
366
|
}
|
|
287
367
|
|
|
368
|
+
/**
|
|
369
|
+
* Handles the case when no props are provided to the constructor.
|
|
370
|
+
* This method can be overridden in child classes to set default values or perform specific initialization logic.
|
|
371
|
+
* By default, it does nothing.
|
|
372
|
+
*
|
|
373
|
+
*
|
|
374
|
+
* @returns
|
|
375
|
+
*/
|
|
376
|
+
fromUndefined(): void {
|
|
377
|
+
this.aseid = new ASEID({
|
|
378
|
+
namespace: (this.constructor as typeof A_Entity).namespace,
|
|
379
|
+
scope: (this.constructor as typeof A_Entity).scope,
|
|
380
|
+
entity: (this.constructor as typeof A_Entity).entity,
|
|
381
|
+
id: `${new Date().getTime().toString()}-${Math.floor(Math.random() * 10000000).toString()}`,
|
|
382
|
+
});
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Create a new entity from constructor object
|
|
388
|
+
* [!] Executed when the constructor is called with an object that does not contain "aseid" property
|
|
389
|
+
* [!] Executes By Default with new A_Entity({}) if getInitializer has not been overridden
|
|
390
|
+
*
|
|
391
|
+
* @param newEntity
|
|
392
|
+
* @returns
|
|
393
|
+
*/
|
|
288
394
|
fromNew(newEntity: _ConstructorType): void {
|
|
289
|
-
|
|
395
|
+
this.aseid = new ASEID({
|
|
396
|
+
namespace: (this.constructor as typeof A_Entity).namespace,
|
|
397
|
+
scope: (this.constructor as typeof A_Entity).scope,
|
|
398
|
+
entity: (this.constructor as typeof A_Entity).entity,
|
|
399
|
+
id: `${new Date().getTime().toString()}-${Math.floor(Math.random() * 10000000).toString()}`,
|
|
400
|
+
});
|
|
290
401
|
|
|
291
402
|
return;
|
|
292
403
|
}
|
|
293
404
|
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Creates a new entity from serialized object
|
|
408
|
+
*
|
|
409
|
+
* [!] Executed when the constructor is called with an object that contains "aseid" property
|
|
410
|
+
* [!] Executes By Default with new A_Entity({ aseid: '...' }) if getInitializer has not been overridden
|
|
411
|
+
*
|
|
412
|
+
*
|
|
413
|
+
* @param serialized
|
|
414
|
+
* @returns
|
|
415
|
+
*/
|
|
294
416
|
fromJSON(serialized: _SerializedType): void {
|
|
295
|
-
this.aseid = new ASEID(
|
|
417
|
+
this.aseid = new ASEID(serialized.aseid);
|
|
296
418
|
return;
|
|
297
419
|
}
|
|
298
420
|
|
|
@@ -300,6 +422,8 @@ export class A_Entity<
|
|
|
300
422
|
|
|
301
423
|
/**
|
|
302
424
|
* Converts the entity to a JSON object
|
|
425
|
+
* [!] This method should be extended in the child classes to include all properties of the entity
|
|
426
|
+
* [!] Includes aseid by default
|
|
303
427
|
*
|
|
304
428
|
*
|
|
305
429
|
* @returns
|
|
@@ -311,6 +435,12 @@ export class A_Entity<
|
|
|
311
435
|
}
|
|
312
436
|
|
|
313
437
|
|
|
438
|
+
/**
|
|
439
|
+
* Returns the string representation of the entity
|
|
440
|
+
* what is basically the ASEID string
|
|
441
|
+
*
|
|
442
|
+
* @returns
|
|
443
|
+
*/
|
|
314
444
|
toString(): string {
|
|
315
445
|
return this.aseid ? this.aseid.toString() : this.constructor.name;
|
|
316
446
|
}
|
|
@@ -9,6 +9,7 @@ import { A_Component } from "../A-Component/A-Component.class";
|
|
|
9
9
|
import { A_Entity } from "../A-Entity/A-Entity.class";
|
|
10
10
|
import {
|
|
11
11
|
A_TYPES__A_InjectDecorator_EntityInjectionInstructions,
|
|
12
|
+
A_TYPES__A_InjectDecorator_EntityInjectionQuery,
|
|
12
13
|
A_TYPES__A_InjectDecorator_Injectable
|
|
13
14
|
} from "@adaas/a-concept/decorators/A-Inject/A-Inject.decorator.types";
|
|
14
15
|
|
|
@@ -176,20 +177,20 @@ export class A_Scope {
|
|
|
176
177
|
* @param component
|
|
177
178
|
* @returns
|
|
178
179
|
*/
|
|
179
|
-
has(
|
|
180
|
-
component:
|
|
180
|
+
has<T extends A_Component>(
|
|
181
|
+
component: new (...args: any[]) => T
|
|
181
182
|
): boolean
|
|
182
|
-
has(
|
|
183
|
-
entity:
|
|
183
|
+
has<T extends A_Entity>(
|
|
184
|
+
entity: new (...args: any[]) => T
|
|
184
185
|
): boolean
|
|
185
|
-
has(
|
|
186
|
-
fragment:
|
|
186
|
+
has<T extends A_Fragment>(
|
|
187
|
+
fragment: new (...args: any[]) => T
|
|
187
188
|
): boolean
|
|
188
189
|
has(
|
|
189
190
|
constructor: string
|
|
190
191
|
): boolean
|
|
191
|
-
has(
|
|
192
|
-
entity:
|
|
192
|
+
has<T extends A_Fragment | A_Component | A_Entity>(
|
|
193
|
+
entity: T | string | (new (...args: any[]) => T)
|
|
193
194
|
): boolean {
|
|
194
195
|
|
|
195
196
|
|
|
@@ -218,31 +219,35 @@ export class A_Scope {
|
|
|
218
219
|
return false;
|
|
219
220
|
}
|
|
220
221
|
|
|
221
|
-
case
|
|
222
|
-
|
|
222
|
+
case typeof entity === 'function'
|
|
223
|
+
&& A_CommonHelper.isInheritedFrom(entity, A_Component): {
|
|
224
|
+
const found = this.params.components.includes(entity as { new(...args: any[]): A_Component });
|
|
223
225
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
+
if (!found && !!this._parent) {
|
|
227
|
+
return this._parent.has(entity as any);
|
|
228
|
+
}
|
|
226
229
|
|
|
227
|
-
|
|
228
|
-
|
|
230
|
+
return found;
|
|
231
|
+
}
|
|
229
232
|
|
|
230
|
-
case
|
|
231
|
-
|
|
233
|
+
case typeof entity === 'function'
|
|
234
|
+
&& A_CommonHelper.isInheritedFrom(entity, A_Entity): {
|
|
235
|
+
const entities = Array.from(this._entities.values());
|
|
232
236
|
|
|
233
|
-
|
|
237
|
+
const found = entities.find(e => e instanceof entity);
|
|
234
238
|
|
|
235
|
-
|
|
236
|
-
|
|
239
|
+
return !!found;
|
|
240
|
+
}
|
|
237
241
|
|
|
238
|
-
case
|
|
239
|
-
|
|
242
|
+
case typeof entity === 'function'
|
|
243
|
+
&& A_CommonHelper.isInheritedFrom(entity, A_Fragment): {
|
|
244
|
+
const found = this._fragments.has(entity);
|
|
240
245
|
|
|
241
|
-
|
|
242
|
-
|
|
246
|
+
if (!found && !!this._parent)
|
|
247
|
+
return this._parent.has(entity as any);
|
|
243
248
|
|
|
244
|
-
|
|
245
|
-
|
|
249
|
+
return found;
|
|
250
|
+
}
|
|
246
251
|
|
|
247
252
|
default: {
|
|
248
253
|
return false;
|
|
@@ -251,7 +256,6 @@ export class A_Scope {
|
|
|
251
256
|
}
|
|
252
257
|
|
|
253
258
|
|
|
254
|
-
|
|
255
259
|
/**
|
|
256
260
|
* Merges two scopes into a new one
|
|
257
261
|
*
|
|
@@ -300,10 +304,10 @@ export class A_Scope {
|
|
|
300
304
|
resolve<T extends A_TYPES__A_InjectDecorator_Injectable>(
|
|
301
305
|
component: T
|
|
302
306
|
): InstanceType<T>
|
|
303
|
-
resolve<T extends
|
|
304
|
-
entity: T,
|
|
305
|
-
instructions: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions
|
|
306
|
-
):
|
|
307
|
+
resolve<T extends A_Entity>(
|
|
308
|
+
entity: { new(...args: any[]): T },
|
|
309
|
+
instructions: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions<T>>
|
|
310
|
+
): T | Array<T>
|
|
307
311
|
resolve<T extends A_TYPES__A_InjectDecorator_Injectable>(
|
|
308
312
|
component: Array<T>
|
|
309
313
|
): Array<InstanceType<T>>
|
|
@@ -313,6 +317,7 @@ export class A_Scope {
|
|
|
313
317
|
param2?: string | Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions>
|
|
314
318
|
): Array<InstanceType<T>> | InstanceType<T> {
|
|
315
319
|
|
|
320
|
+
|
|
316
321
|
switch (true) {
|
|
317
322
|
case Array.isArray(param1): {
|
|
318
323
|
return param1.map(c => this.resolveOnce(param1 as any, param2 as any));
|
|
@@ -372,7 +377,7 @@ export class A_Scope {
|
|
|
372
377
|
|
|
373
378
|
switch (true) {
|
|
374
379
|
case A_CommonHelper.isInheritedFrom(component, A_Entity): {
|
|
375
|
-
return this.resolveEntity(component as
|
|
380
|
+
return this.resolveEntity(component as any, instructions) as InstanceType<T>;
|
|
376
381
|
}
|
|
377
382
|
|
|
378
383
|
case A_CommonHelper.isInheritedFrom(component, A_Fragment): {
|
|
@@ -395,18 +400,18 @@ export class A_Scope {
|
|
|
395
400
|
|
|
396
401
|
private resolveEntity<T extends { new(...args: any[]): A_Entity }>(
|
|
397
402
|
entity: T,
|
|
398
|
-
instructions?: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions
|
|
399
|
-
): InstanceType<T> | undefined {
|
|
403
|
+
instructions?: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions<InstanceType<T>>>
|
|
404
|
+
): InstanceType<T> | undefined | InstanceType<T>[] {
|
|
400
405
|
|
|
401
|
-
const query = instructions?.query || {}
|
|
406
|
+
const query = instructions?.query || {} as Partial<A_TYPES__A_InjectDecorator_EntityInjectionQuery<InstanceType<T>>>;
|
|
402
407
|
const count = instructions?.pagination?.count || 1;
|
|
403
408
|
|
|
404
|
-
|
|
405
409
|
switch (true) {
|
|
406
410
|
case !instructions: {
|
|
407
411
|
|
|
408
412
|
const entities = Array.from(this._entities.values());
|
|
409
413
|
|
|
414
|
+
|
|
410
415
|
const found = entities.find(e => e instanceof entity);
|
|
411
416
|
|
|
412
417
|
switch (true) {
|
|
@@ -417,7 +422,7 @@ export class A_Scope {
|
|
|
417
422
|
return this._parent.resolveEntity(entity, instructions);
|
|
418
423
|
|
|
419
424
|
default:
|
|
420
|
-
throw new Error(`
|
|
425
|
+
throw new Error(`Entity ${entity.name} not found in the scope ${this.name}`);
|
|
421
426
|
}
|
|
422
427
|
}
|
|
423
428
|
|
|
@@ -428,6 +433,7 @@ export class A_Scope {
|
|
|
428
433
|
}
|
|
429
434
|
|
|
430
435
|
case !!query.aseid
|
|
436
|
+
&& typeof query.aseid === 'object'
|
|
431
437
|
&& query.aseid instanceof ASEID
|
|
432
438
|
&& this._entities.has(query.aseid.toString()): {
|
|
433
439
|
return this._entities.get(query.aseid.toString()) as InstanceType<T>;
|
|
@@ -441,16 +447,35 @@ export class A_Scope {
|
|
|
441
447
|
const found = entities.filter(
|
|
442
448
|
e => e instanceof entity
|
|
443
449
|
).find(e => {
|
|
444
|
-
|
|
445
|
-
|
|
446
450
|
return String(e.id) === String(query.id)
|
|
447
451
|
});
|
|
448
452
|
|
|
449
453
|
return found as InstanceType<T>;
|
|
450
454
|
}
|
|
451
455
|
|
|
452
|
-
default:
|
|
453
|
-
|
|
456
|
+
default: {
|
|
457
|
+
const entities = Array.from(this._entities.values());
|
|
458
|
+
|
|
459
|
+
const found = entities.filter(
|
|
460
|
+
e => e instanceof entity
|
|
461
|
+
).filter(e => {
|
|
462
|
+
return Object.entries(query).every(([key, value]) => {
|
|
463
|
+
if (key in e) {
|
|
464
|
+
return (e as any)[key] === value;
|
|
465
|
+
}
|
|
466
|
+
return false;
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
if (found.length === 0 && !!this._parent)
|
|
471
|
+
return this._parent.resolveEntity(entity, instructions);
|
|
472
|
+
|
|
473
|
+
if (count === 1)
|
|
474
|
+
return found[0] as InstanceType<T>;
|
|
475
|
+
|
|
476
|
+
return found as InstanceType<T>[];
|
|
477
|
+
}
|
|
478
|
+
|
|
454
479
|
}
|
|
455
480
|
}
|
|
456
481
|
|
|
@@ -460,6 +485,7 @@ export class A_Scope {
|
|
|
460
485
|
|
|
461
486
|
const fragmentInstancePresented = this.fragments.some(fr => fr instanceof fragment);
|
|
462
487
|
|
|
488
|
+
|
|
463
489
|
switch (true) {
|
|
464
490
|
|
|
465
491
|
case fragmentInstancePresented && this._fragments.has(fragment):
|
|
@@ -545,17 +571,27 @@ export class A_Scope {
|
|
|
545
571
|
*
|
|
546
572
|
* @param fragment
|
|
547
573
|
*/
|
|
574
|
+
register<T extends A_Component>(component: new (...args: any[]) => T): void
|
|
548
575
|
register(entity: A_Entity): void
|
|
549
576
|
register(component: A_Component): void
|
|
550
577
|
register(fragment: A_Fragment): void
|
|
551
578
|
register(
|
|
552
|
-
param1: A_Fragment | A_Component | A_Entity
|
|
579
|
+
param1: A_Fragment | A_Component | A_Entity | (new (...args: any[]) => A_Component)
|
|
553
580
|
): void {
|
|
581
|
+
switch (true) {
|
|
582
|
+
case param1 instanceof A_Component && !this._components.has(param1.constructor): {
|
|
583
|
+
this._components.set(param1.constructor, param1);
|
|
554
584
|
|
|
585
|
+
const allowedComponent = this.components.find(c => c === param1.constructor);
|
|
555
586
|
|
|
556
|
-
|
|
587
|
+
if (!allowedComponent) {
|
|
588
|
+
this.components.push(param1.constructor as any);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
A_Context.register(this, param1);
|
|
592
|
+
break;
|
|
593
|
+
}
|
|
557
594
|
|
|
558
|
-
switch (true) {
|
|
559
595
|
case param1 instanceof A_Entity && !this._entities.has(param1.aseid.toString()): {
|
|
560
596
|
this._entities.set(param1.aseid.toString(), param1);
|
|
561
597
|
A_Context.register(this, param1);
|
|
@@ -587,6 +623,13 @@ export class A_Scope {
|
|
|
587
623
|
break;
|
|
588
624
|
}
|
|
589
625
|
|
|
626
|
+
case typeof param1 === 'function' && A_CommonHelper.isInheritedFrom(param1, A_Component): {
|
|
627
|
+
const allowedComponent = this.components.find(c => c === param1);
|
|
628
|
+
|
|
629
|
+
if (!allowedComponent)
|
|
630
|
+
this.components.push(param1);
|
|
631
|
+
break;
|
|
632
|
+
}
|
|
590
633
|
default:
|
|
591
634
|
if (param1 instanceof A_Entity)
|
|
592
635
|
throw new Error(`Entity with ASEID ${param1.aseid.toString()} is already registered in the scope ${this.name}`);
|
|
@@ -6,6 +6,7 @@ import { A_Container } from "../A-Container/A-Container.class";
|
|
|
6
6
|
import { A_Scope } from "../A-Scope/A-Scope.class";
|
|
7
7
|
import { A_StageError } from "./A-Stage.error";
|
|
8
8
|
import { A_FeatureCaller } from "../A-Feature/A-FeatureCaller.class";
|
|
9
|
+
import { A_Entity } from "../A-Entity/A-Entity.class";
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -30,10 +31,10 @@ export class A_Stage {
|
|
|
30
31
|
this._steps = _steps;
|
|
31
32
|
this.name = `${this.feature.name}::a-stage:[sync:${this
|
|
32
33
|
.syncSteps
|
|
33
|
-
.map(s => s.component.name + '.' + s.handler)
|
|
34
|
+
.map(s => typeof s.component === 'string' ? s.component : s.component.name + '.' + s.handler)
|
|
34
35
|
.join(' -> ')}][async:${this
|
|
35
36
|
.asyncSteps
|
|
36
|
-
.map(s => s.component.name + '.' + s.handler)
|
|
37
|
+
.map(s => typeof s.component === 'string' ? s.component : s.component.name + '.' + s.handler)
|
|
37
38
|
.join(' -> ')}]`;
|
|
38
39
|
|
|
39
40
|
}
|
|
@@ -87,9 +88,11 @@ export class A_Stage {
|
|
|
87
88
|
return Promise
|
|
88
89
|
.all(A_Context
|
|
89
90
|
.meta(
|
|
90
|
-
|
|
91
|
+
// TODO: fix types
|
|
92
|
+
(step.component instanceof A_Container
|
|
91
93
|
? step.component.constructor
|
|
92
|
-
: step.component
|
|
94
|
+
: step.component) as any
|
|
95
|
+
|
|
93
96
|
)
|
|
94
97
|
.injections(step.handler)
|
|
95
98
|
.map(async arg => {
|
|
@@ -100,7 +103,7 @@ export class A_Stage {
|
|
|
100
103
|
if (A_CommonHelper.isInheritedFrom(arg.target, A_Feature))
|
|
101
104
|
return this.feature;
|
|
102
105
|
|
|
103
|
-
return scope.resolve(arg.target)
|
|
106
|
+
return scope.resolve((arg as any).target, (arg as any).instructions)
|
|
104
107
|
})
|
|
105
108
|
)
|
|
106
109
|
}
|
|
@@ -134,10 +137,11 @@ export class A_Stage {
|
|
|
134
137
|
// TODO: probably would be better to do it another way. let's think about it
|
|
135
138
|
const instance = component instanceof A_Container
|
|
136
139
|
? component
|
|
137
|
-
:
|
|
140
|
+
// TODO: fix types
|
|
141
|
+
: this.feature.Scope.resolve(component as any);
|
|
138
142
|
|
|
139
143
|
if (!instance)
|
|
140
|
-
throw new Error(`Unable to resolve component ${component.name}`);
|
|
144
|
+
throw new Error(`Unable to resolve component ${typeof component === 'string' ? component : component.name} from scope ${this.feature.Scope.name}`);
|
|
141
145
|
|
|
142
146
|
if (!instance[handler])
|
|
143
147
|
throw new Error(`Handler ${handler} not found in ${instance.constructor.name}`);
|