@adaas/a-concept 0.1.36 → 0.1.38
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.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/global/A-Entity/A-Entity.meta.ts +18 -0
- package/src/global/A-Entity/A-Entity.types.ts +13 -0
- package/src/global/A-Feature/A-Feature.class.ts +32 -6
- package/src/global/A-Inject/A-Inject.decorator.ts +5 -0
- package/tests/A-Feature.test.ts +57 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adaas/a-concept",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.38",
|
|
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
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -2,6 +2,7 @@ import { A_Meta } from "../A-Meta/A-Meta.class";
|
|
|
2
2
|
import { A_TYPES__EntityMeta } from "./A-Entity.types";
|
|
3
3
|
import { A_TYPES__EntityMetaKey } from "./A-Entity.constants";
|
|
4
4
|
import { A_TYPES__FeatureDefineDecoratorMeta } from "../A-Feature/A-Feature.types";
|
|
5
|
+
import { A_TYPES__A_InjectDecorator_Meta } from "../A-Inject/A-Inject.types";
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
export class A_EntityMeta extends A_Meta<A_TYPES__EntityMeta> {
|
|
@@ -20,4 +21,21 @@ export class A_EntityMeta extends A_Meta<A_TYPES__EntityMeta> {
|
|
|
20
21
|
.map(([, feature]) => feature) || [];
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Allows to get all the injections for a given handler
|
|
27
|
+
*
|
|
28
|
+
* @param handler
|
|
29
|
+
* @returns
|
|
30
|
+
*/
|
|
31
|
+
injections(
|
|
32
|
+
handler: string
|
|
33
|
+
): A_TYPES__A_InjectDecorator_Meta {
|
|
34
|
+
const injections = this.get(A_TYPES__EntityMetaKey.INJECTIONS);
|
|
35
|
+
|
|
36
|
+
const args = injections?.get(handler) || [];
|
|
37
|
+
|
|
38
|
+
return args;
|
|
39
|
+
}
|
|
40
|
+
|
|
23
41
|
}
|
|
@@ -3,6 +3,7 @@ import { A_Entity } from "./A-Entity.class";
|
|
|
3
3
|
import { ASEID } from "../ASEID/ASEID.class";
|
|
4
4
|
import { A_TYPES__EntityMetaKey } from "./A-Entity.constants";
|
|
5
5
|
import { A_TYPES__FeatureDefineDecoratorMeta, A_TYPES__FeatureExtendDecoratorMeta } from "../A-Feature/A-Feature.types";
|
|
6
|
+
import { A_TYPES__A_InjectDecorator_Meta } from "../A-Inject/A-Inject.types";
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -67,6 +68,18 @@ export type A_TYPES__EntityMeta = {
|
|
|
67
68
|
*/
|
|
68
69
|
[Key: string]: A_TYPES__FeatureDefineDecoratorMeta
|
|
69
70
|
}>
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Injections defined on the component per handler
|
|
74
|
+
*/
|
|
75
|
+
[A_TYPES__EntityMetaKey.INJECTIONS]: A_Meta<{
|
|
76
|
+
/**
|
|
77
|
+
* Where Key is the name of the injection
|
|
78
|
+
*
|
|
79
|
+
* Where value is the list of injections
|
|
80
|
+
*/
|
|
81
|
+
[Key: string]: A_TYPES__A_InjectDecorator_Meta
|
|
82
|
+
}>
|
|
70
83
|
}
|
|
71
84
|
|
|
72
85
|
|
|
@@ -248,9 +248,22 @@ export class A_Feature<T extends A_TYPES__FeatureAvailableComponents = A_TYPES__
|
|
|
248
248
|
this._name = params.name;
|
|
249
249
|
|
|
250
250
|
// 2) get scope from where feature is called
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
251
|
+
// 2) get scope from where feature is called
|
|
252
|
+
let componentScope: A_Scope | undefined;
|
|
253
|
+
// uses to extend a component scope if component is not registered in the context
|
|
254
|
+
let externalScope: A_Scope | undefined = params.scope;
|
|
255
|
+
|
|
256
|
+
try {
|
|
257
|
+
if (params.component)
|
|
258
|
+
componentScope = A_Context.scope(params.component);
|
|
259
|
+
} catch (error) {
|
|
260
|
+
if (!externalScope)
|
|
261
|
+
throw error;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (componentScope && externalScope && !externalScope.isInheritedFrom(componentScope)) {
|
|
265
|
+
externalScope.inherit(componentScope);
|
|
266
|
+
}
|
|
254
267
|
|
|
255
268
|
// 3) create caller wrapper for the simple injection of the caller component
|
|
256
269
|
// - Just to prevent issues with undefined caller in features without component
|
|
@@ -261,7 +274,7 @@ export class A_Feature<T extends A_TYPES__FeatureAvailableComponents = A_TYPES__
|
|
|
261
274
|
const scope = A_Context.allocate(this);
|
|
262
275
|
|
|
263
276
|
// 5) ensure that the scope of the caller component is inherited by the feature scope
|
|
264
|
-
scope.inherit(componentScope);
|
|
277
|
+
scope.inherit(componentScope || externalScope!);
|
|
265
278
|
|
|
266
279
|
// 6) create steps manager to organize steps into stages
|
|
267
280
|
this._SM = new A_StepsManager(params.template);
|
|
@@ -291,7 +304,20 @@ export class A_Feature<T extends A_TYPES__FeatureAvailableComponents = A_TYPES__
|
|
|
291
304
|
this._name = params.name;
|
|
292
305
|
|
|
293
306
|
// 2) get scope from where feature is called
|
|
294
|
-
|
|
307
|
+
let componentScope: A_Scope | undefined;
|
|
308
|
+
// uses to extend a component scope if component is not registered in the context
|
|
309
|
+
let externalScope: A_Scope | undefined = params.scope;
|
|
310
|
+
|
|
311
|
+
try {
|
|
312
|
+
componentScope = A_Context.scope(params.component);
|
|
313
|
+
} catch (error) {
|
|
314
|
+
if (!externalScope)
|
|
315
|
+
throw error;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (componentScope && externalScope && !externalScope.isInheritedFrom(componentScope)) {
|
|
319
|
+
externalScope.inherit(componentScope);
|
|
320
|
+
}
|
|
295
321
|
|
|
296
322
|
// 3) create caller wrapper for the simple injection of the caller component
|
|
297
323
|
this._caller = new A_Caller<T>(params.component);
|
|
@@ -300,7 +326,7 @@ export class A_Feature<T extends A_TYPES__FeatureAvailableComponents = A_TYPES__
|
|
|
300
326
|
const scope = A_Context.allocate(this);
|
|
301
327
|
|
|
302
328
|
// 5) ensure that the scope of the caller component is inherited by the feature scope
|
|
303
|
-
scope.inherit(componentScope);
|
|
329
|
+
scope.inherit(componentScope || externalScope!);
|
|
304
330
|
|
|
305
331
|
// 6) retrieve the template from the context
|
|
306
332
|
const template = A_Context.featureTemplate(this._name, this._caller.component, scope);
|
|
@@ -25,6 +25,7 @@ import { A_Feature } from "@adaas/a-concept/global/A-Feature/A-Feature.class";
|
|
|
25
25
|
import { A_CommonHelper } from "@adaas/a-concept/helpers/A_Common.helper";
|
|
26
26
|
import { A_TYPES__Error_Constructor } from "../A-Error/A_Error.types";
|
|
27
27
|
import { A_Error } from "../A-Error/A_Error.class";
|
|
28
|
+
import { A_TYPES__EntityMetaKey } from "../A-Entity/A-Entity.constants";
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
/**
|
|
@@ -153,6 +154,10 @@ export function A_Inject(
|
|
|
153
154
|
case A_TypeGuards.isContainerInstance(target):
|
|
154
155
|
metaKey = A_TYPES__ContainerMetaKey.INJECTIONS;
|
|
155
156
|
break;
|
|
157
|
+
|
|
158
|
+
case A_TypeGuards.isEntityInstance(target):
|
|
159
|
+
metaKey = A_TYPES__EntityMetaKey.INJECTIONS;
|
|
160
|
+
break;
|
|
156
161
|
}
|
|
157
162
|
|
|
158
163
|
// get existing meta or create a new one
|
package/tests/A-Feature.test.ts
CHANGED
|
@@ -362,4 +362,61 @@ describe('A-Feature tests', () => {
|
|
|
362
362
|
|
|
363
363
|
expect(executionOrder).toEqual(['stepOne', 'stepThree']);
|
|
364
364
|
});
|
|
365
|
+
|
|
366
|
+
it('Should allow proceed with external scope', async () => {
|
|
367
|
+
const executionOrder: string[] = [];
|
|
368
|
+
|
|
369
|
+
class CustomComponent extends A_Component {
|
|
370
|
+
|
|
371
|
+
doSomething() {
|
|
372
|
+
executionOrder.push('customComponentAction');
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// 1) create a base component with some feature
|
|
378
|
+
class ComponentA extends A_Component {
|
|
379
|
+
|
|
380
|
+
@A_Feature.Define({ invoke: false })
|
|
381
|
+
async feature1() {
|
|
382
|
+
const scope = new A_Scope({ name: 'ExternalScopeCaller', components: [CustomComponent] });
|
|
383
|
+
|
|
384
|
+
executionOrder.push('stepOne');
|
|
385
|
+
|
|
386
|
+
await this.call('feature1', scope);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
class ComponentB extends A_Component {
|
|
392
|
+
|
|
393
|
+
@A_Feature.Extend({
|
|
394
|
+
name: 'feature1',
|
|
395
|
+
})
|
|
396
|
+
async feature1Extension(
|
|
397
|
+
@A_Inject(A_Scope) scope: A_Scope,
|
|
398
|
+
@A_Inject(CustomComponent) customComponent: CustomComponent
|
|
399
|
+
) {
|
|
400
|
+
expect(customComponent).toBeInstanceOf(CustomComponent);
|
|
401
|
+
expect(customComponent.doSomething).toBeInstanceOf(Function);
|
|
402
|
+
|
|
403
|
+
executionOrder.push('stepThree');
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
// 2) create a running scope
|
|
409
|
+
const scope = new A_Scope({ name: 'TestScope' , components: [ComponentA, ComponentB] });
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
// 3) create an instance of the component from the scope
|
|
413
|
+
const myComponent = scope.resolve(ComponentA)!;
|
|
414
|
+
expect(myComponent).toBeInstanceOf(ComponentA);
|
|
415
|
+
|
|
416
|
+
await myComponent.feature1();
|
|
417
|
+
|
|
418
|
+
expect(executionOrder).toEqual(['stepOne', 'stepThree']);
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
|
|
365
422
|
});
|