@adaas/a-concept 0.1.59 → 0.1.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adaas/a-concept",
3
- "version": "0.1.59",
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.",
3
+ "version": "0.1.61",
4
+ "description": "A-Concept is a framework of the new generation that is tailored to use AI, enabling developers to create AI-powered applications with ease. It provides a structured approach to building, managing, and deploying AI-driven solutions.",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.mjs",
@@ -16,9 +16,9 @@
16
16
  "url": "git+https://github.com/ADAAS-org/adaas-a-concept.git"
17
17
  },
18
18
  "keywords": [
19
- "sdk",
20
- "ai",
21
- "rag"
19
+ "adaas",
20
+ "ai framework",
21
+ "a-concept"
22
22
  ],
23
23
  "bugs": {
24
24
  "url": "https://github.com/ADAAS-org/adaas-a-concept/issues"
@@ -6,7 +6,7 @@ import { A_TYPES__ComponentMetaKey } from "./A-Component.constants";
6
6
  import { A_TYPES__FeatureDefineDecoratorMeta } from "../A-Feature/A-Feature.types";
7
7
 
8
8
 
9
- export class A_ComponentMeta extends A_Meta<A_TYPES__ComponentMeta> {
9
+ export class A_ComponentMeta<T extends A_TYPES__ComponentMeta = A_TYPES__ComponentMeta> extends A_Meta<T> {
10
10
 
11
11
  /**
12
12
  * Allows to get all the injections for a given handler
@@ -37,6 +37,7 @@ import { A_Fragment } from "../A-Fragment/A-Fragment.class";
37
37
  import { A_TYPES__InjectableTargets } from "../A-Inject/A-Inject.types";
38
38
  import { A_TYPES__ConceptAbstractions } from "../A-Concept/A-Concept.constants";
39
39
  import { A_CommonHelper } from "@adaas/a-concept/helpers/A_Common.helper";
40
+ import { A_TYPES__Fragment_Constructor } from "../A-Fragment/A-Fragment.types";
40
41
 
41
42
 
42
43
 
@@ -117,6 +118,9 @@ export class A_Context {
117
118
 
118
119
 
119
120
 
121
+
122
+ protected _globals = new Map<string, any>();
123
+
120
124
  /**
121
125
  * Private constructor to enforce singleton pattern.
122
126
  *
@@ -346,54 +350,72 @@ export class A_Context {
346
350
  *
347
351
  * @param container
348
352
  */
349
- static meta(
353
+ static meta<T extends A_ContainerMeta>(
350
354
  /**
351
355
  * Get meta for the specific container class by constructor.
352
356
  */
353
357
  container: A_TYPES__Container_Constructor,
354
- ): A_ContainerMeta
355
- static meta(
358
+ ): T
359
+ static meta<T extends A_ContainerMeta>(
356
360
  /**
357
361
  * Get meta for the specific container instance.
358
362
  */
359
363
  container: A_Container,
360
- ): A_ContainerMeta
361
- static meta(
364
+ ): T
365
+ static meta<T extends A_EntityMeta>(
362
366
  /**
363
367
  * Get meta for the specific entity class by constructor.
364
368
  */
365
369
  entity: A_TYPES__Entity_Constructor,
366
- ): A_EntityMeta
367
- static meta(
370
+ ): T
371
+ static meta<T extends A_EntityMeta>(
368
372
  /**
369
373
  * Get meta for the specific entity instance.
370
374
  */
371
375
  entity: A_Entity,
372
- ): A_EntityMeta
373
- static meta(
376
+ ): T
377
+ static meta<T extends A_ComponentMeta>(
374
378
  /**
375
379
  * Get meta for the specific component class by constructor.
376
380
  */
377
381
  component: A_TYPES__Component_Constructor,
378
- ): A_ComponentMeta
379
- static meta(
382
+ ): T
383
+ static meta<T extends A_ComponentMeta>(
380
384
  /**
381
385
  * Get meta for the specific component instance.
382
386
  */
383
387
  component: A_Component,
384
- ): A_ComponentMeta
385
- static meta(
388
+ ): T
389
+ static meta<T extends A_Meta>(
390
+ /**
391
+ * Get meta for the specific component class by constructor.
392
+ */
393
+ fragment: A_TYPES__Fragment_Constructor,
394
+ ): T
395
+ static meta<T extends A_Meta>(
396
+ /**
397
+ * Get meta for the specific component instance.
398
+ */
399
+ fragment: A_Fragment,
400
+ ): T
401
+ static meta<T extends A_ComponentMeta>(
386
402
  /**
387
403
  * Get meta for the specific component by its name.
388
404
  */
389
405
  component: string,
390
- ): A_ComponentMeta
406
+ ): T
391
407
  static meta(
392
408
  /**
393
- * Get meta for the specific injectable target (class or instance).
409
+ * Get meta for the specific meta linked component (class or instance).
394
410
  */
395
- target: A_TYPES__InjectableTargets,
411
+ target: A_TYPES__MetaLinkedComponentConstructors | A_TYPES__MetaLinkedComponents,
396
412
  ): A_ComponentMeta
413
+ static meta<T extends A_Meta>(
414
+ /**
415
+ * Get meta for the specific class or instance
416
+ */
417
+ constructor: new (...args: any[]) => any
418
+ ): T
397
419
  static meta<T extends Record<string, any>>(
398
420
  /**
399
421
  * Get meta for the specific class or instance
@@ -469,7 +491,21 @@ export class A_Context {
469
491
 
470
492
  break;
471
493
  }
472
- // 7) If param1 is string then we need to find the component by its name
494
+ // 7) If param1 is instance of A_Fragment
495
+ case A_TypeGuards.isFragmentInstance(param1): {
496
+ property = param1.constructor as A_TYPES__Fragment_Constructor;
497
+ metaType = A_ComponentMeta;
498
+
499
+ break;
500
+ }
501
+ // 8) If param1 is class of A_Fragment
502
+ case A_TypeGuards.isFragmentConstructor(param1): {
503
+ property = param1;
504
+ metaType = A_EntityMeta;
505
+
506
+ break;
507
+ }
508
+ // 9) If param1 is string then we need to find the component by its name
473
509
  case typeof param1 === 'string': {
474
510
  const found = Array.from(instance._metaStorage)
475
511
  .find(([c]) => c.name === param1
@@ -484,7 +520,7 @@ export class A_Context {
484
520
 
485
521
  break;
486
522
  }
487
- // 8) If param1 is any other class or function
523
+ // 10) If param1 is any other class or function
488
524
  default: {
489
525
  property = param1;
490
526
  metaType = A_Meta;
@@ -504,6 +540,47 @@ export class A_Context {
504
540
  }
505
541
 
506
542
 
543
+
544
+ /**
545
+ * Allows to set meta for the specific class or instance.
546
+ *
547
+ * @param param1
548
+ * @param meta
549
+ */
550
+ static setMeta<T extends A_ContainerMeta, S extends A_Container>(
551
+ param1: S,
552
+ meta: T
553
+ )
554
+ static setMeta<T extends A_EntityMeta, S extends A_Entity>(
555
+ param1: S,
556
+ meta: T
557
+ )
558
+ static setMeta<T extends A_ComponentMeta, S extends A_Component>(
559
+ param1: S,
560
+ meta: T
561
+ )
562
+ static setMeta<T extends A_Meta>(
563
+ param1: new (...args: any[]) => any,
564
+ meta: T
565
+ )
566
+ static setMeta<T extends A_Meta>(
567
+ param1: A_TYPES__MetaLinkedComponentConstructors | A_TYPES__MetaLinkedComponents,
568
+ meta: T
569
+ ) {
570
+ const instance = A_Context.getInstance();
571
+
572
+ const existingMeta = A_Context.meta(param1);
573
+
574
+ const constructor = typeof param1 === 'function'
575
+ ? param1
576
+ : param1.constructor as A_TYPES__MetaLinkedComponentConstructors;
577
+
578
+ instance._metaStorage.set(constructor, existingMeta ? meta.from(existingMeta) : meta);
579
+ }
580
+
581
+
582
+
583
+
507
584
  /**
508
585
  *
509
586
  * This method allows to get the issuer of a specific scope.
@@ -134,6 +134,12 @@ export class A_Error<
134
134
  */
135
135
  error: Error
136
136
  )
137
+ constructor(
138
+ /**
139
+ * Original JS Error
140
+ */
141
+ error: unknown
142
+ )
137
143
  constructor(
138
144
  /**
139
145
  * Error message
@@ -145,7 +151,7 @@ export class A_Error<
145
151
  description: string
146
152
  )
147
153
  constructor(
148
- param1: _ConstructorType | Error | string | A_Error,
154
+ param1: _ConstructorType | Error | string | A_Error | any,
149
155
  param2?: string
150
156
  ) {
151
157
  // to prevent errors accumulation in the stack trace it returns the original error if provided param1 is A_Error
@@ -178,10 +184,7 @@ export class A_Error<
178
184
  break;
179
185
 
180
186
  default:
181
- throw new A_Error(
182
- A_CONSTANTS__ERROR_CODES.VALIDATION_ERROR,
183
- 'Invalid parameters provided to A_Error constructor'
184
- );
187
+ super('An unknown error occurred.');
185
188
  }
186
189
 
187
190
  const initializer = this.getInitializer(param1, param2);
@@ -1,13 +1,28 @@
1
+ import { A_MetaDecorator } from "./A-Meta.decorator";
2
+ import { A_TYPES__Meta_Constructor } from "./A-Meta.types";
3
+
1
4
  /**
2
5
  * A Meta is an entity that stores all the metadata for the specific entity like container, component, feature, etc.
3
6
  *
4
7
  * [!] Meta can be different depending on the type of input data
5
8
  */
6
9
  export class A_Meta<
7
- _StorageItems extends Record<string, any> = any,
10
+ _StorageItems extends Record<any, any> = any,
8
11
  _SerializedType extends Record<string, any> = Record<string, any>
9
12
  > implements Iterable<[keyof _StorageItems, _StorageItems[keyof _StorageItems]]> {
10
13
 
14
+ /**
15
+ * Allows to set a custom meta class for the Component or Container or Entity, or anything else.
16
+ *
17
+ * @param target
18
+ * @returns
19
+ */
20
+ static Define<T extends A_Meta>(target: A_TYPES__Meta_Constructor<T>) {
21
+ return A_MetaDecorator(target);
22
+ }
23
+
24
+
25
+
11
26
  protected meta: Map<keyof _StorageItems, _StorageItems[keyof _StorageItems]> = new Map();
12
27
 
13
28
 
@@ -0,0 +1,26 @@
1
+ import { A_Context } from "../A-Context/A-Context.class";
2
+ import { A_Meta } from "./A-Meta.class";
3
+ import { A_TYPES__MetaLinkedComponentConstructors } from "./A-Meta.types";
4
+
5
+
6
+
7
+
8
+ /**
9
+ *
10
+ * This decorator should allow to set a default meta type for the class, this helps to avoid
11
+ * the need to create custom meta classes for each class.
12
+ *
13
+ * @returns
14
+ */
15
+ export function A_MetaDecorator<T extends A_Meta>(
16
+ constructor: new (...args: any[]) => T
17
+ ) {
18
+ return function <TTarget extends A_TYPES__MetaLinkedComponentConstructors>(
19
+ target: TTarget
20
+ ): TTarget {
21
+ // Store meta info on the target class itself for the Meta decorator to pick up
22
+ A_Context.setMeta(target, new constructor());
23
+
24
+ return target;
25
+ };
26
+ }
@@ -4,18 +4,31 @@ import { A_Container } from "../A-Container/A-Container.class";
4
4
  import { A_TYPES__Container_Constructor } from "../A-Container/A-Container.types";
5
5
  import { A_Entity } from "../A-Entity/A-Entity.class";
6
6
  import { A_TYPES__Entity_Constructor } from "../A-Entity/A-Entity.types";
7
+ import { A_Fragment } from "../A-Fragment/A-Fragment.class";
8
+ import { A_TYPES__Fragment_Constructor } from "../A-Fragment/A-Fragment.types";
9
+ import { A_Meta } from "./A-Meta.class";
7
10
 
8
11
 
12
+ // ============================================================================
13
+ // --------------------------- Primary Types ----------------------------------
14
+ // ============================================================================
15
+ /**
16
+ * Meta constructor type
17
+ */
18
+ export type A_TYPES__Meta_Constructor<T = A_Meta> = new (...args: any[]) => T;
9
19
  /**
10
20
  * Components that can have Meta associated with them
11
21
  */
12
22
  export type A_TYPES__MetaLinkedComponents = A_Container
13
23
  | A_Component
14
24
  | A_Entity
25
+ | A_Fragment
15
26
  /**
16
27
  * Constructors of components that can have Meta associated with them
17
28
  */
18
- export type A_TYPES__MetaLinkedComponentConstructors = A_TYPES__Container_Constructor
29
+ export type A_TYPES__MetaLinkedComponentConstructors = new (...args: any[]) => any
30
+ | A_TYPES__Container_Constructor
19
31
  | A_TYPES__Component_Constructor
20
32
  | A_TYPES__Entity_Constructor
33
+ | A_TYPES__Fragment_Constructor
21
34
 
@@ -1045,7 +1045,16 @@ export class A_Scope<
1045
1045
  */
1046
1046
  entity: A_TYPES__Entity_Constructor<T>
1047
1047
  ): T | undefined
1048
-
1048
+ resolveFlat<T extends A_Entity>(
1049
+ /**
1050
+ * Provide an entity constructor to resolve its instance or an array of instances from the scope
1051
+ */
1052
+ entity: A_TYPES__Entity_Constructor<T>,
1053
+ /**
1054
+ * Only Aseid Provided, in this case one entity will be returned
1055
+ */
1056
+ instructions: { query: { aseid: string | ASEID } }
1057
+ ): T | undefined
1049
1058
  resolveFlat<T extends A_Entity>(
1050
1059
  /**
1051
1060
  * Provide an entity constructor to resolve its instance or an array of instances from the scope
@@ -148,6 +148,14 @@ export class ASEID {
148
148
  return this._shard;
149
149
  }
150
150
 
151
+ /**
152
+ * Get the hash of the ASEID, Unique identifier based on the ASEID string
153
+ * Useful when aseid details should not be exposed directly
154
+ */
155
+ get hash(): string {
156
+ return A_IdentityHelper.hashString(this.toString());
157
+ }
158
+
151
159
  /**
152
160
  * get Internal Initializer based on the type of the parameter provided
153
161
  *
@@ -49,5 +49,23 @@ export class A_IdentityHelper {
49
49
  return String(Number(formattedNumber)); // Convert to number and back to string to remove leading zeros
50
50
  }
51
51
 
52
+ /**
53
+ * Generates a simple hash string from the input string.
54
+ *
55
+ *
56
+ * @param input
57
+ * @returns
58
+ */
59
+ static hashString(input: string): string {
60
+ let hash = 0, i, chr;
61
+ if (input.length === 0) return hash.toString();
62
+ for (i = 0; i < input.length; i++) {
63
+ chr = input.charCodeAt(i);
64
+ hash = ((hash << 5) - hash) + chr;
65
+ hash |= 0; // Convert to 32bit integer
66
+ }
67
+ return hash.toString();
68
+ }
69
+
52
70
 
53
71
  }
package/src/index.ts CHANGED
@@ -65,6 +65,7 @@ export { A_ScopeError } from './global/A-Scope/A-Scope.error';
65
65
  export * from './global/A-Scope/A-Scope.types';
66
66
 
67
67
  export { A_Meta } from './global/A-Meta/A-Meta.class';
68
+ export { A_MetaDecorator } from './global/A-Meta/A-Meta.decorator';
68
69
  export * from './global/A-Meta/A-Meta.types';
69
70
 
70
71
  export { A_Fragment } from './global/A-Fragment/A-Fragment.class';
@@ -5,6 +5,8 @@ import { A_Concept } from "@adaas/a-concept/global/A-Concept/A-Concept.class";
5
5
  import { A_Context } from "@adaas/a-concept/global/A-Context/A-Context.class";
6
6
  import { A_Feature } from "@adaas/a-concept/global/A-Feature/A-Feature.class";
7
7
  import { A_Meta } from "@adaas/a-concept/global/A-Meta/A-Meta.class";
8
+ import { A_Inject } from "@adaas/a-concept/global/A-Inject/A-Inject.decorator";
9
+ import { A_TYPES__ComponentMeta } from "@adaas/a-concept/global/A-Component/A-Component.types";
8
10
 
9
11
  jest.retryTimes(0);
10
12
 
@@ -128,4 +130,45 @@ describe('A-Meta tests', () => {
128
130
  expect(metaE.get(A_TYPES__ComponentMetaKey.EXTENSIONS)?.get('.*\\.testFeature$')?.map(e => e.handler)).toContain('test3');
129
131
  expect(metaE.get(A_TYPES__ComponentMetaKey.EXTENSIONS)?.get('.*\\.testFeature$')?.map(e => e.handler)).not.toContain('test2');
130
132
  })
133
+ it('Should allow to inherit meta properly', async () => {
134
+
135
+ class InjectableComponent extends A_Component { }
136
+
137
+ class CustomComponentMeta extends A_ComponentMeta<{ customField: string } & A_TYPES__ComponentMeta> {
138
+
139
+ get customField(): string | undefined {
140
+ return this.get('customField');
141
+ }
142
+ }
143
+
144
+ @A_Meta.Define(CustomComponentMeta)
145
+ class CustomComponent extends A_Component {
146
+
147
+ static Test(){
148
+
149
+ }
150
+
151
+ constructor(
152
+ @A_Inject(InjectableComponent) public injectableComponent: InjectableComponent
153
+ ) {
154
+ super();
155
+ }
156
+
157
+ @A_Feature.Extend({
158
+ name: 'testFeature'
159
+ })
160
+ async feature() {
161
+
162
+ }
163
+ }
164
+
165
+
166
+ const meta = A_Context.meta<CustomComponentMeta>(CustomComponent);
167
+
168
+ expect(meta).toBeInstanceOf(CustomComponentMeta);
169
+ expect(meta).toHaveProperty('customField');
170
+
171
+ expect(meta.get(A_TYPES__ComponentMetaKey.EXTENSIONS)?.size()).toBe(1);
172
+ expect(meta.get(A_TYPES__ComponentMetaKey.EXTENSIONS)?.has('.*\\.testFeature$')).toBe(true);
173
+ })
131
174
  })
@@ -22,6 +22,41 @@ describe('ASEID Tests', () => {
22
22
  expect(aseid.version).toBe('v1');
23
23
  expect(aseid.shard).toBe('shard1');
24
24
  expect(aseid.toString()).toBe('my-concept@my-scope:my-entity:shard1.123@v1');
25
+ });
26
+ it('Should allow to create a new ASEID and use hash for identity', async () => {
27
+ const aseid1 = new ASEID({
28
+ concept: 'my-concept',
29
+ scope: 'my-scope',
30
+ entity: 'my-entity',
31
+ id: '123',
32
+ version: 'v1',
33
+ shard: 'shard1'
34
+ });
35
+
36
+ const aseid2 = new ASEID({
37
+ concept: 'my-concept',
38
+ scope: 'my-scope',
39
+ entity: 'my-entity',
40
+ id: '123',
41
+ version: 'v1',
42
+ shard: 'shard1'
43
+ });
44
+
45
+ const aseid3 = new ASEID({
46
+ concept: 'my-concept',
47
+ scope: 'my-scope',
48
+ entity: 'my-entity',
49
+ id: '124',
50
+ version: 'v1',
51
+ shard: 'shard1'
52
+ });
53
+
54
+ expect(aseid1.hash).toBeDefined();
55
+ expect(aseid2.hash).toBeDefined();
56
+ expect(aseid3.hash).toBeDefined();
57
+
58
+ expect(aseid1.hash).not.toBe(aseid3.hash);
59
+ expect(aseid1.hash).toBe(aseid2.hash);
25
60
  });
26
61
  it('Should allow to create a new ASEID object with required parameters only', async () => {
27
62
  const aseid = new ASEID({