@adaas/a-concept 0.0.63 → 0.1.1

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 (412) hide show
  1. package/dist/index.d.ts +24 -32
  2. package/dist/index.js +35 -52
  3. package/dist/index.js.map +1 -1
  4. package/dist/src/constants/env.constants.d.ts +15 -8
  5. package/dist/src/constants/env.constants.js +17 -10
  6. package/dist/src/constants/env.constants.js.map +1 -1
  7. package/dist/src/global/A-Abstraction/A-Abstraction-Extend.decorator.d.ts +23 -0
  8. package/dist/src/global/A-Abstraction/A-Abstraction-Extend.decorator.js +69 -0
  9. package/dist/src/global/A-Abstraction/A-Abstraction-Extend.decorator.js.map +1 -0
  10. package/dist/src/global/A-Abstraction/A-Abstraction.class.d.ts +47 -20
  11. package/dist/src/global/A-Abstraction/A-Abstraction.class.js +55 -48
  12. package/dist/src/global/A-Abstraction/A-Abstraction.class.js.map +1 -1
  13. package/dist/src/global/A-Abstraction/A-Abstraction.error.d.ts +7 -0
  14. package/dist/src/global/A-Abstraction/A-Abstraction.error.js +12 -0
  15. package/dist/src/global/A-Abstraction/A-Abstraction.error.js.map +1 -0
  16. package/dist/src/global/A-Abstraction/A-Abstraction.types.d.ts +27 -12
  17. package/dist/src/global/A-Abstraction/A-Abstraction.types.js +0 -8
  18. package/dist/src/global/A-Abstraction/A-Abstraction.types.js.map +1 -1
  19. package/dist/src/global/A-Caller/A_Caller.class.d.ts +33 -0
  20. package/dist/src/global/A-Caller/A_Caller.class.js +44 -0
  21. package/dist/src/global/A-Caller/A_Caller.class.js.map +1 -0
  22. package/dist/src/global/A-Caller/A_Caller.error.d.ts +7 -0
  23. package/dist/src/global/A-Caller/A_Caller.error.js +12 -0
  24. package/dist/src/global/A-Caller/A_Caller.error.js.map +1 -0
  25. package/dist/src/global/A-Caller/A_Caller.types.d.ts +18 -0
  26. package/dist/src/{base/A-Errors/A-Errors.types.js → global/A-Caller/A_Caller.types.js} +1 -1
  27. package/dist/src/global/A-Caller/A_Caller.types.js.map +1 -0
  28. package/dist/src/global/A-Component/A-Component.class.d.ts +20 -3
  29. package/dist/src/global/A-Component/A-Component.class.js +35 -19
  30. package/dist/src/global/A-Component/A-Component.class.js.map +1 -1
  31. package/dist/src/global/A-Component/A-Component.constants.d.ts +6 -0
  32. package/dist/src/global/A-Component/A-Component.constants.js +11 -0
  33. package/dist/src/global/A-Component/A-Component.constants.js.map +1 -0
  34. package/dist/src/global/A-Component/A-Component.meta.d.ts +4 -4
  35. package/dist/src/global/A-Component/A-Component.meta.js +6 -8
  36. package/dist/src/global/A-Component/A-Component.meta.js.map +1 -1
  37. package/dist/src/global/A-Component/A-Component.types.d.ts +40 -22
  38. package/dist/src/global/A-Component/A-Component.types.js +1 -8
  39. package/dist/src/global/A-Component/A-Component.types.js.map +1 -1
  40. package/dist/src/global/A-Concept/A-Concept.class.d.ts +153 -0
  41. package/dist/src/global/A-Concept/A-Concept.class.js +260 -0
  42. package/dist/src/global/A-Concept/A-Concept.class.js.map +1 -0
  43. package/dist/src/global/A-Concept/A-Concept.constants.d.ts +33 -0
  44. package/dist/src/global/A-Concept/A-Concept.constants.js +39 -0
  45. package/dist/src/global/A-Concept/A-Concept.constants.js.map +1 -0
  46. package/dist/src/global/A-Concept/{A_Concept.meta.js → A-Concept.meta.js} +1 -2
  47. package/dist/src/global/A-Concept/A-Concept.meta.js.map +1 -0
  48. package/dist/src/global/A-Concept/A-Concept.types.d.ts +83 -0
  49. package/dist/src/global/{A-Channel/A-Channel.types.js → A-Concept/A-Concept.types.js} +1 -1
  50. package/dist/src/global/A-Concept/A-Concept.types.js.map +1 -0
  51. package/dist/src/global/A-Container/A-Container.class.d.ts +31 -35
  52. package/dist/src/global/A-Container/A-Container.class.js +34 -55
  53. package/dist/src/global/A-Container/A-Container.class.js.map +1 -1
  54. package/dist/src/global/A-Container/A-Container.constants.d.ts +5 -0
  55. package/dist/src/global/A-Container/A-Container.constants.js +10 -0
  56. package/dist/src/global/A-Container/A-Container.constants.js.map +1 -0
  57. package/dist/src/global/A-Container/A-Container.meta.d.ts +6 -6
  58. package/dist/src/global/A-Container/A-Container.meta.js +5 -6
  59. package/dist/src/global/A-Container/A-Container.meta.js.map +1 -1
  60. package/dist/src/global/A-Container/A-Container.types.d.ts +31 -25
  61. package/dist/src/global/A-Container/A-Container.types.js +1 -7
  62. package/dist/src/global/A-Container/A-Container.types.js.map +1 -1
  63. package/dist/src/global/A-Context/A-Context.class.d.ts +302 -76
  64. package/dist/src/global/A-Context/A-Context.class.js +436 -244
  65. package/dist/src/global/A-Context/A-Context.class.js.map +1 -1
  66. package/dist/src/global/A-Context/A-Context.error.d.ts +20 -0
  67. package/dist/src/global/A-Context/A-Context.error.js +25 -0
  68. package/dist/src/global/A-Context/A-Context.error.js.map +1 -0
  69. package/dist/src/global/A-Context/A-Context.types.d.ts +5 -0
  70. package/dist/src/global/A-Context/A-Context.types.js +1 -0
  71. package/dist/src/global/A-Entity/A-Entity.class.d.ts +18 -18
  72. package/dist/src/global/A-Entity/A-Entity.class.js +36 -43
  73. package/dist/src/global/A-Entity/A-Entity.class.js.map +1 -1
  74. package/dist/src/global/A-Entity/A-Entity.constants.d.ts +11 -0
  75. package/dist/src/global/A-Entity/A-Entity.constants.js +17 -0
  76. package/dist/src/global/A-Entity/A-Entity.constants.js.map +1 -0
  77. package/dist/src/global/A-Entity/A-Entity.error.d.ts +7 -0
  78. package/dist/src/global/A-Entity/A-Entity.error.js +12 -0
  79. package/dist/src/global/A-Entity/A-Entity.error.js.map +1 -0
  80. package/dist/src/global/A-Entity/A-Entity.meta.d.ts +2 -2
  81. package/dist/src/global/A-Entity/A-Entity.meta.js +2 -2
  82. package/dist/src/global/A-Entity/A-Entity.meta.js.map +1 -1
  83. package/dist/src/global/A-Entity/A-Entity.types.d.ts +24 -29
  84. package/dist/src/global/A-Entity/A-Entity.types.js +1 -13
  85. package/dist/src/global/A-Entity/A-Entity.types.js.map +1 -1
  86. package/dist/src/global/A-Error/A_Error.class.d.ts +219 -0
  87. package/dist/src/global/A-Error/A_Error.class.js +267 -0
  88. package/dist/src/global/A-Error/A_Error.class.js.map +1 -0
  89. package/dist/src/global/A-Error/A_Error.constants.d.ts +5 -0
  90. package/dist/src/global/A-Error/A_Error.constants.js +9 -0
  91. package/dist/src/global/A-Error/A_Error.constants.js.map +1 -0
  92. package/dist/src/global/A-Error/A_Error.types.d.ts +89 -0
  93. package/dist/src/{decorators/A-Inject/A-Inject.decorator.types.js → global/A-Error/A_Error.types.js} +1 -1
  94. package/dist/src/global/A-Error/A_Error.types.js.map +1 -0
  95. package/dist/src/global/A-Feature/A-Feature-Define.decorator.d.ts +15 -0
  96. package/dist/src/{decorators → global}/A-Feature/A-Feature-Define.decorator.js +21 -27
  97. package/dist/src/global/A-Feature/A-Feature-Define.decorator.js.map +1 -0
  98. package/dist/src/{decorators → global}/A-Feature/A-Feature-Extend.decorator.d.ts +26 -3
  99. package/dist/src/global/A-Feature/A-Feature-Extend.decorator.js +97 -0
  100. package/dist/src/global/A-Feature/A-Feature-Extend.decorator.js.map +1 -0
  101. package/dist/src/global/A-Feature/A-Feature.class.d.ts +120 -30
  102. package/dist/src/global/A-Feature/A-Feature.class.js +205 -73
  103. package/dist/src/global/A-Feature/A-Feature.class.js.map +1 -1
  104. package/dist/src/global/A-Feature/A-Feature.error.d.ts +25 -0
  105. package/dist/src/global/A-Feature/A-Feature.error.js +33 -0
  106. package/dist/src/global/A-Feature/A-Feature.error.js.map +1 -0
  107. package/dist/src/global/A-Feature/A-Feature.types.d.ts +241 -18
  108. package/dist/src/global/A-Feature/A-Feature.types.js +16 -22
  109. package/dist/src/global/A-Feature/A-Feature.types.js.map +1 -1
  110. package/dist/src/global/A-Fragment/A-Fragment.class.d.ts +19 -27
  111. package/dist/src/global/A-Fragment/A-Fragment.class.js +21 -91
  112. package/dist/src/global/A-Fragment/A-Fragment.class.js.map +1 -1
  113. package/dist/src/global/A-Fragment/A-Fragment.types.d.ts +19 -1
  114. package/dist/src/global/A-Fragment/A-Fragment.types.js +3 -0
  115. package/dist/src/global/A-Fragment/A-Fragment.types.js.map +1 -1
  116. package/dist/src/global/A-Inject/A-Inject.decorator.d.ts +80 -0
  117. package/dist/src/global/A-Inject/A-Inject.decorator.js +49 -0
  118. package/dist/src/global/A-Inject/A-Inject.decorator.js.map +1 -0
  119. package/dist/src/global/A-Inject/A-Inject.error.d.ts +5 -0
  120. package/dist/src/global/A-Inject/A-Inject.error.js +10 -0
  121. package/dist/src/global/A-Inject/A-Inject.error.js.map +1 -0
  122. package/dist/src/global/A-Inject/A-Inject.types.d.ts +42 -0
  123. package/dist/src/{decorators/A-Entity/A-Entity.decorator.types.js → global/A-Inject/A-Inject.types.js} +1 -1
  124. package/dist/src/global/A-Inject/A-Inject.types.js.map +1 -0
  125. package/dist/src/global/A-Meta/A-Meta.class.d.ts +1 -1
  126. package/dist/src/global/A-Meta/A-Meta.types.d.ts +14 -0
  127. package/dist/src/global/A-Meta/A-Meta.types.js +1 -0
  128. package/dist/src/global/A-Scope/A-Scope.class.d.ts +406 -63
  129. package/dist/src/global/A-Scope/A-Scope.class.js +533 -287
  130. package/dist/src/global/A-Scope/A-Scope.class.js.map +1 -1
  131. package/dist/src/global/A-Scope/A-Scope.error.d.ts +6 -0
  132. package/dist/src/global/A-Scope/A-Scope.error.js +11 -0
  133. package/dist/src/global/A-Scope/A-Scope.error.js.map +1 -0
  134. package/dist/src/global/A-Scope/A-Scope.types.d.ts +50 -13
  135. package/dist/src/global/A-Stage/A-Stage.class.d.ts +31 -23
  136. package/dist/src/global/A-Stage/A-Stage.class.js +100 -68
  137. package/dist/src/global/A-Stage/A-Stage.class.js.map +1 -1
  138. package/dist/src/global/A-Stage/A-Stage.error.d.ts +2 -1
  139. package/dist/src/global/A-Stage/A-Stage.error.js +5 -2
  140. package/dist/src/global/A-Stage/A-Stage.error.js.map +1 -1
  141. package/dist/src/global/A-Stage/A-Stage.types.d.ts +4 -16
  142. package/dist/src/global/A-Stage/A-Stage.types.js +0 -16
  143. package/dist/src/global/A-Stage/A-Stage.types.js.map +1 -1
  144. package/dist/src/global/ASEID/ASEID.class.d.ts +130 -0
  145. package/dist/src/global/ASEID/ASEID.class.js +167 -0
  146. package/dist/src/global/ASEID/ASEID.class.js.map +1 -0
  147. package/dist/src/global/ASEID/ASEID.constants.js +2 -0
  148. package/dist/src/global/ASEID/ASEID.constants.js.map +1 -0
  149. package/dist/src/global/ASEID/ASEID.error.d.ts +5 -0
  150. package/dist/src/global/ASEID/ASEID.error.js +10 -0
  151. package/dist/src/global/ASEID/ASEID.error.js.map +1 -0
  152. package/dist/src/global/ASEID/ASEID.types.d.ts +65 -0
  153. package/dist/src/global/ASEID/ASEID.types.js +5 -0
  154. package/dist/src/global/ASEID/ASEID.types.js.map +1 -0
  155. package/dist/src/helpers/A_Common.helper.d.ts +28 -0
  156. package/dist/src/helpers/A_Common.helper.js +170 -0
  157. package/dist/src/helpers/A_Common.helper.js.map +1 -0
  158. package/dist/src/helpers/A_Formatter.helper.d.ts +35 -0
  159. package/dist/src/helpers/A_Formatter.helper.js +62 -0
  160. package/dist/src/helpers/A_Formatter.helper.js.map +1 -0
  161. package/dist/src/helpers/A_Identity.helper.d.ts +29 -0
  162. package/dist/src/helpers/A_Identity.helper.js +43 -0
  163. package/dist/src/helpers/A_Identity.helper.js.map +1 -0
  164. package/dist/src/helpers/{StepsManager.class.d.ts → A_StepsManager.class.d.ts} +4 -2
  165. package/dist/src/helpers/{StepsManager.class.js → A_StepsManager.class.js} +10 -5
  166. package/dist/src/helpers/A_StepsManager.class.js.map +1 -0
  167. package/dist/src/helpers/A_TypeGuards.helper.d.ts +205 -0
  168. package/dist/src/helpers/A_TypeGuards.helper.js +288 -0
  169. package/dist/src/helpers/A_TypeGuards.helper.js.map +1 -0
  170. package/dist/src/types/A_Common.types.d.ts +36 -0
  171. package/dist/src/types/A_Common.types.js +3 -0
  172. package/dist/src/types/A_Common.types.js.map +1 -0
  173. package/index.ts +27 -51
  174. package/jest.config.ts +1 -0
  175. package/package.json +1 -2
  176. package/src/constants/env.constants.ts +18 -11
  177. package/src/global/A-Abstraction/A-Abstraction-Extend.decorator.ts +103 -0
  178. package/src/global/A-Abstraction/A-Abstraction.class.ts +71 -65
  179. package/src/global/A-Abstraction/A-Abstraction.error.ts +9 -0
  180. package/src/global/A-Abstraction/A-Abstraction.types.ts +52 -13
  181. package/src/global/A-Caller/A_Caller.class.ts +61 -0
  182. package/src/global/A-Caller/A_Caller.error.ts +10 -0
  183. package/src/global/A-Caller/A_Caller.types.ts +25 -0
  184. package/src/global/A-Component/A-Component.class.ts +26 -15
  185. package/src/global/A-Component/A-Component.constants.ts +9 -0
  186. package/src/global/A-Component/A-Component.meta.ts +6 -16
  187. package/src/global/A-Component/A-Component.types.ts +53 -28
  188. package/src/global/A-Concept/A-Concept.class.ts +316 -0
  189. package/src/global/A-Concept/A-Concept.constants.ts +36 -0
  190. package/src/global/A-Concept/A-Concept.meta.ts +17 -0
  191. package/src/global/A-Concept/A-Concept.types.ts +100 -0
  192. package/src/global/A-Container/A-Container.class.ts +42 -83
  193. package/src/global/A-Container/A-Container.constants.ts +5 -0
  194. package/src/global/A-Container/A-Container.meta.ts +7 -11
  195. package/src/global/A-Container/A-Container.types.ts +38 -34
  196. package/src/global/A-Context/A-Context.class.ts +648 -412
  197. package/src/global/A-Context/A-Context.error.ts +44 -0
  198. package/src/global/A-Context/A-Context.types.ts +14 -0
  199. package/src/global/A-Entity/A-Entity.class.ts +39 -52
  200. package/src/global/A-Entity/A-Entity.constants.ts +12 -0
  201. package/src/global/A-Entity/A-Entity.error.ts +12 -0
  202. package/src/global/A-Entity/A-Entity.meta.ts +4 -4
  203. package/src/global/A-Entity/A-Entity.types.ts +31 -36
  204. package/src/global/A-Error/A_Error.class.ts +408 -0
  205. package/src/global/A-Error/A_Error.constants.ts +11 -0
  206. package/src/global/A-Error/A_Error.types.ts +96 -0
  207. package/src/{decorators → global}/A-Feature/A-Feature-Define.decorator.ts +31 -37
  208. package/src/global/A-Feature/A-Feature-Extend.decorator.ts +187 -0
  209. package/src/global/A-Feature/A-Feature.class.ts +279 -122
  210. package/src/global/A-Feature/A-Feature.error.ts +33 -0
  211. package/src/global/A-Feature/A-Feature.types.ts +278 -40
  212. package/src/global/A-Fragment/A-Fragment.class.ts +29 -100
  213. package/src/global/A-Fragment/A-Fragment.types.ts +25 -3
  214. package/src/global/A-Inject/A-Inject.decorator.ts +167 -0
  215. package/src/global/A-Inject/A-Inject.error.ts +8 -0
  216. package/src/global/A-Inject/A-Inject.types.ts +75 -0
  217. package/src/global/A-Meta/A-Meta.class.ts +1 -1
  218. package/src/global/A-Meta/A-Meta.types.ts +21 -0
  219. package/src/global/A-Scope/A-Scope.class.ts +841 -443
  220. package/src/global/A-Scope/A-Scope.error.ts +13 -0
  221. package/src/global/A-Scope/A-Scope.types.ts +65 -26
  222. package/src/global/A-Stage/A-Stage.class.ts +142 -80
  223. package/src/global/A-Stage/A-Stage.error.ts +4 -2
  224. package/src/global/A-Stage/A-Stage.types.ts +4 -25
  225. package/src/global/ASEID/ASEID.class.ts +275 -0
  226. package/src/global/ASEID/ASEID.error.ts +12 -0
  227. package/src/global/ASEID/ASEID.types.ts +79 -0
  228. package/src/helpers/A_Common.helper.ts +204 -0
  229. package/src/helpers/A_Formatter.helper.ts +58 -0
  230. package/src/helpers/A_Identity.helper.ts +53 -0
  231. package/src/helpers/{StepsManager.class.ts → A_StepsManager.class.ts} +19 -3
  232. package/src/helpers/A_TypeGuards.helper.ts +318 -0
  233. package/src/types/A_Common.types.ts +79 -0
  234. package/tests/A-Common.test.ts +117 -0
  235. package/tests/A-Component.test.ts +11 -6
  236. package/tests/A-Concept.test.ts +19 -22
  237. package/tests/A-Entity.test.ts +24 -24
  238. package/tests/A-Error.test.ts +129 -0
  239. package/tests/A-Feature.test.ts +34 -25
  240. package/tests/A-Scope.test.ts +50 -22
  241. package/tests/ASEID.test.ts +74 -0
  242. package/tsconfig.build.json +2 -1
  243. package/tsconfig.json +3 -2
  244. package/dist/src/base/A-Config/A-Config.container.d.ts +0 -9
  245. package/dist/src/base/A-Config/A-Config.container.js +0 -69
  246. package/dist/src/base/A-Config/A-Config.container.js.map +0 -1
  247. package/dist/src/base/A-Config/A-Config.context.d.ts +0 -30
  248. package/dist/src/base/A-Config/A-Config.context.js +0 -60
  249. package/dist/src/base/A-Config/A-Config.context.js.map +0 -1
  250. package/dist/src/base/A-Config/A-Config.types.d.ts +0 -20
  251. package/dist/src/base/A-Config/A-Config.types.js +0 -7
  252. package/dist/src/base/A-Config/A-Config.types.js.map +0 -1
  253. package/dist/src/base/A-Config/components/ConfigReader.component.d.ts +0 -29
  254. package/dist/src/base/A-Config/components/ConfigReader.component.js +0 -84
  255. package/dist/src/base/A-Config/components/ConfigReader.component.js.map +0 -1
  256. package/dist/src/base/A-Config/components/ENVConfigReader.component.d.ts +0 -10
  257. package/dist/src/base/A-Config/components/ENVConfigReader.component.js +0 -37
  258. package/dist/src/base/A-Config/components/ENVConfigReader.component.js.map +0 -1
  259. package/dist/src/base/A-Config/components/FileConfigReader.component.d.ts +0 -11
  260. package/dist/src/base/A-Config/components/FileConfigReader.component.js +0 -48
  261. package/dist/src/base/A-Config/components/FileConfigReader.component.js.map +0 -1
  262. package/dist/src/base/A-Errors/A-Error.entity.d.ts +0 -3
  263. package/dist/src/base/A-Errors/A-Error.entity.js +0 -8
  264. package/dist/src/base/A-Errors/A-Error.entity.js.map +0 -1
  265. package/dist/src/base/A-Errors/A-Errors.component.d.ts +0 -19
  266. package/dist/src/base/A-Errors/A-Errors.component.js +0 -87
  267. package/dist/src/base/A-Errors/A-Errors.component.js.map +0 -1
  268. package/dist/src/base/A-Errors/A-Errors.context.d.ts +0 -27
  269. package/dist/src/base/A-Errors/A-Errors.context.js +0 -50
  270. package/dist/src/base/A-Errors/A-Errors.context.js.map +0 -1
  271. package/dist/src/base/A-Errors/A-Errors.types.d.ts +0 -5
  272. package/dist/src/base/A-Errors/A-Errors.types.js.map +0 -1
  273. package/dist/src/base/A-Logger/A-Logger.component.d.ts +0 -31
  274. package/dist/src/base/A-Logger/A-Logger.component.js +0 -155
  275. package/dist/src/base/A-Logger/A-Logger.component.js.map +0 -1
  276. package/dist/src/base/A-Logger/A-Logger.types.js +0 -2
  277. package/dist/src/base/A-Logger/A-Logger.types.js.map +0 -1
  278. package/dist/src/base/A-Polyfill/A-Polyfill.component.d.ts +0 -5
  279. package/dist/src/base/A-Polyfill/A-Polyfill.component.js +0 -34
  280. package/dist/src/base/A-Polyfill/A-Polyfill.component.js.map +0 -1
  281. package/dist/src/decorators/A-Abstraction/A-Abstraction-Extend.decorator.d.ts +0 -14
  282. package/dist/src/decorators/A-Abstraction/A-Abstraction-Extend.decorator.js +0 -53
  283. package/dist/src/decorators/A-Abstraction/A-Abstraction-Extend.decorator.js.map +0 -1
  284. package/dist/src/decorators/A-Abstraction/A-Abstraction.decorator.types.d.ts +0 -2
  285. package/dist/src/decorators/A-Abstraction/A-Abstraction.decorator.types.js +0 -3
  286. package/dist/src/decorators/A-Abstraction/A-Abstraction.decorator.types.js.map +0 -1
  287. package/dist/src/decorators/A-Connect/A-Connect.decorator.d.ts +0 -19
  288. package/dist/src/decorators/A-Connect/A-Connect.decorator.js +0 -31
  289. package/dist/src/decorators/A-Connect/A-Connect.decorator.js.map +0 -1
  290. package/dist/src/decorators/A-Connect/A-Connect.decorator.types.d.ts +0 -1
  291. package/dist/src/decorators/A-Connect/A-Connect.decorator.types.js +0 -3
  292. package/dist/src/decorators/A-Connect/A-Connect.decorator.types.js.map +0 -1
  293. package/dist/src/decorators/A-Entity/A-Entity-List.decorator.d.ts +0 -1
  294. package/dist/src/decorators/A-Entity/A-Entity-List.decorator.js +0 -8
  295. package/dist/src/decorators/A-Entity/A-Entity-List.decorator.js.map +0 -1
  296. package/dist/src/decorators/A-Entity/A-Entity.decorator.types.d.ts +0 -14
  297. package/dist/src/decorators/A-Entity/A-Entity.decorator.types.js.map +0 -1
  298. package/dist/src/decorators/A-Feature/A-Feature-Define.decorator.d.ts +0 -19
  299. package/dist/src/decorators/A-Feature/A-Feature-Define.decorator.js.map +0 -1
  300. package/dist/src/decorators/A-Feature/A-Feature-Extend.decorator.js +0 -81
  301. package/dist/src/decorators/A-Feature/A-Feature-Extend.decorator.js.map +0 -1
  302. package/dist/src/decorators/A-Feature/A-Feature.decorator.types.d.ts +0 -96
  303. package/dist/src/decorators/A-Feature/A-Feature.decorator.types.js +0 -3
  304. package/dist/src/decorators/A-Feature/A-Feature.decorator.types.js.map +0 -1
  305. package/dist/src/decorators/A-Inject/A-Inject.decorator.d.ts +0 -30
  306. package/dist/src/decorators/A-Inject/A-Inject.decorator.js +0 -47
  307. package/dist/src/decorators/A-Inject/A-Inject.decorator.js.map +0 -1
  308. package/dist/src/decorators/A-Inject/A-Inject.decorator.types.d.ts +0 -48
  309. package/dist/src/decorators/A-Inject/A-Inject.decorator.types.js.map +0 -1
  310. package/dist/src/global/A-Channel/A-Channel.class.d.ts +0 -16
  311. package/dist/src/global/A-Channel/A-Channel.class.js +0 -59
  312. package/dist/src/global/A-Channel/A-Channel.class.js.map +0 -1
  313. package/dist/src/global/A-Channel/A-Channel.types.d.ts +0 -68
  314. package/dist/src/global/A-Channel/A-Channel.types.js.map +0 -1
  315. package/dist/src/global/A-Command/A-Command.class.d.ts +0 -187
  316. package/dist/src/global/A-Command/A-Command.class.js +0 -349
  317. package/dist/src/global/A-Command/A-Command.class.js.map +0 -1
  318. package/dist/src/global/A-Command/A-Command.constants.d.ts +0 -17
  319. package/dist/src/global/A-Command/A-Command.constants.js +0 -22
  320. package/dist/src/global/A-Command/A-Command.constants.js.map +0 -1
  321. package/dist/src/global/A-Command/A-Command.meta.d.ts +0 -11
  322. package/dist/src/global/A-Command/A-Command.meta.js +0 -18
  323. package/dist/src/global/A-Command/A-Command.meta.js.map +0 -1
  324. package/dist/src/global/A-Command/A-Command.types.d.ts +0 -43
  325. package/dist/src/global/A-Command/A-Command.types.js +0 -10
  326. package/dist/src/global/A-Command/A-Command.types.js.map +0 -1
  327. package/dist/src/global/A-Command/context/A_Command.context.d.ts +0 -64
  328. package/dist/src/global/A-Command/context/A_Command.context.js +0 -85
  329. package/dist/src/global/A-Command/context/A_Command.context.js.map +0 -1
  330. package/dist/src/global/A-Concept/A_Concept.class.d.ts +0 -104
  331. package/dist/src/global/A-Concept/A_Concept.class.js +0 -217
  332. package/dist/src/global/A-Concept/A_Concept.class.js.map +0 -1
  333. package/dist/src/global/A-Concept/A_Concept.meta.js.map +0 -1
  334. package/dist/src/global/A-Concept/A_Concept.types.d.ts +0 -103
  335. package/dist/src/global/A-Concept/A_Concept.types.js +0 -28
  336. package/dist/src/global/A-Concept/A_Concept.types.js.map +0 -1
  337. package/dist/src/global/A-Feature/A-FeatureCaller.class.d.ts +0 -22
  338. package/dist/src/global/A-Feature/A-FeatureCaller.class.js +0 -26
  339. package/dist/src/global/A-Feature/A-FeatureCaller.class.js.map +0 -1
  340. package/dist/src/helpers/StepsManager.class.js.map +0 -1
  341. package/dist/src/types/A_Module.types.d.ts +0 -17
  342. package/dist/src/types/A_Module.types.js +0 -22
  343. package/dist/src/types/A_Module.types.js.map +0 -1
  344. package/examples/entity/concept.ts +0 -68
  345. package/examples/entity/entities/Task.entity.ts +0 -110
  346. package/examples/entity/entities/User.entity.ts +0 -62
  347. package/examples/fe-be/channels/Test.channel.ts +0 -27
  348. package/examples/fe-be/components/BE-Controller.component.ts +0 -20
  349. package/examples/fe-be/components/FE.component.ts +0 -13
  350. package/examples/fe-be/containers/ServerApp.container.ts +0 -8
  351. package/examples/fe-be/containers/WebApp.container.ts +0 -13
  352. package/examples/multi-container/channels/Direct.channel.ts +0 -39
  353. package/examples/multi-container/concept.ts +0 -0
  354. package/examples/multi-container/containers/Command.container.ts +0 -41
  355. package/examples/multi-container/containers/Schedule.container.ts +0 -52
  356. package/examples/simple/components/A.component.ts +0 -71
  357. package/examples/simple/components/B.component.ts +0 -68
  358. package/examples/simple/concept.ts +0 -87
  359. package/examples/simple/containers/Main.container.ts +0 -88
  360. package/examples/simple/containers/Secondary.container.ts +0 -26
  361. package/examples/simple/context/Fragment_A.context.ts +0 -25
  362. package/examples/simple/context/Fragment_B.context.ts +0 -19
  363. package/examples/simple/entities/EntityA.entity.ts +0 -32
  364. package/examples/simple-http-server/components/http-error-handler.component.ts +0 -47
  365. package/examples/simple-http-server/components/http-request-handler.component.ts +0 -13
  366. package/examples/simple-http-server/concept.ts +0 -35
  367. package/examples/simple-http-server/containers/http-server.container.ts +0 -57
  368. package/examples/simple-http-server/contexts/http-request.context.ts +0 -59
  369. package/examples/simple-http-server/contexts/http-server.context.types.ts +0 -0
  370. package/examples/simple-http-server/controllers/orders.controller.ts +0 -20
  371. package/examples/simple-http-server/controllers/users.controller.ts +0 -104
  372. package/examples/simple-http-server/test.ts +0 -290
  373. package/src/base/A-Config/A-Config.container.ts +0 -68
  374. package/src/base/A-Config/A-Config.context.ts +0 -114
  375. package/src/base/A-Config/A-Config.types.ts +0 -28
  376. package/src/base/A-Config/components/ConfigReader.component.ts +0 -68
  377. package/src/base/A-Config/components/ENVConfigReader.component.ts +0 -31
  378. package/src/base/A-Config/components/FileConfigReader.component.ts +0 -41
  379. package/src/base/A-Errors/A-Error.entity.ts +0 -10
  380. package/src/base/A-Errors/A-Errors.component.ts +0 -103
  381. package/src/base/A-Errors/A-Errors.context.ts +0 -90
  382. package/src/base/A-Errors/A-Errors.types.ts +0 -6
  383. package/src/base/A-Logger/A-Logger.component.ts +0 -192
  384. package/src/base/A-Logger/A-Logger.types.ts +0 -0
  385. package/src/base/A-Polyfill/A-Polyfill.component.ts +0 -18
  386. package/src/decorators/A-Abstraction/A-Abstraction-Extend.decorator.ts +0 -81
  387. package/src/decorators/A-Abstraction/A-Abstraction.decorator.types.ts +0 -21
  388. package/src/decorators/A-Connect/A-Connect.decorator.ts +0 -71
  389. package/src/decorators/A-Connect/A-Connect.decorator.types.ts +0 -6
  390. package/src/decorators/A-Entity/A-Entity-List.decorator.ts +0 -12
  391. package/src/decorators/A-Entity/A-Entity.decorator.types.ts +0 -18
  392. package/src/decorators/A-Feature/A-Feature-Extend.decorator.ts +0 -151
  393. package/src/decorators/A-Feature/A-Feature.decorator.types.ts +0 -142
  394. package/src/decorators/A-Inject/A-Inject.decorator.ts +0 -119
  395. package/src/decorators/A-Inject/A-Inject.decorator.types.ts +0 -85
  396. package/src/global/A-Channel/A-Channel.class.ts +0 -111
  397. package/src/global/A-Channel/A-Channel.types.ts +0 -114
  398. package/src/global/A-Command/A-Command.class.ts +0 -419
  399. package/src/global/A-Command/A-Command.constants.ts +0 -27
  400. package/src/global/A-Command/A-Command.meta.ts +0 -22
  401. package/src/global/A-Command/A-Command.types.ts +0 -73
  402. package/src/global/A-Command/context/A_Command.context.ts +0 -114
  403. package/src/global/A-Concept/A_Concept.class.ts +0 -298
  404. package/src/global/A-Concept/A_Concept.meta.ts +0 -32
  405. package/src/global/A-Concept/A_Concept.types.ts +0 -143
  406. package/src/global/A-Feature/A-FeatureCaller.class.ts +0 -38
  407. package/src/types/A_Module.types.ts +0 -23
  408. package/tests/A-Command.test.ts +0 -133
  409. package/tests/A-Config.test.ts +0 -172
  410. /package/dist/src/global/A-Concept/{A_Concept.meta.d.ts → A-Concept.meta.d.ts} +0 -0
  411. /package/dist/src/{base/A-Logger/A-Logger.types.d.ts → global/ASEID/ASEID.constants.d.ts} +0 -0
  412. /package/{examples/fe-be/concept.ts → src/global/ASEID/ASEID.constants.ts} +0 -0
@@ -1,275 +1,413 @@
1
- import { A_CommonHelper, ASEID } from "@adaas/a-utils";
2
- import { A_TYPES__ScopeConfig, A_TYPES__ScopeConstructor } from "./A-Scope.types";
3
- import { A_Fragment } from "../A-Fragment/A-Fragment.class";
4
- import { A_Context } from "../A-Context/A-Context.class";
5
1
  import {
6
- A_TYPES__ComponentMetaKey
7
- } from "../A-Component/A-Component.types";
8
- import { A_Component } from "../A-Component/A-Component.class";
9
- import { A_Entity } from "../A-Entity/A-Entity.class";
2
+ A_TYPES__ScopeConfig,
3
+ A_TYPES__Scope_Init,
4
+ A_TYPES__ScopeLinkedComponents,
5
+ A_TYPES__ScopeResolvableComponents,
6
+ A_TYPES__Scope_Constructor
7
+ } from './A-Scope.types'
10
8
  import {
11
9
  A_TYPES__A_InjectDecorator_EntityInjectionInstructions,
12
10
  A_TYPES__A_InjectDecorator_EntityInjectionQuery,
13
- A_TYPES__A_InjectDecorator_Injectable
14
- } from "@adaas/a-concept/decorators/A-Inject/A-Inject.decorator.types";
15
- import { A_Command } from "../A-Command/A-Command.class";
16
-
11
+ A_TYPES__InjectableConstructors,
12
+ } from "@adaas/a-concept/global/A-Inject/A-Inject.types";
13
+ import { A_Fragment } from "../A-Fragment/A-Fragment.class";
14
+ import { A_Context } from "../A-Context/A-Context.class";
15
+ import { A_Component } from "../A-Component/A-Component.class";
16
+ import { A_Entity } from "../A-Entity/A-Entity.class";
17
+ import { A_TypeGuards } from "@adaas/a-concept/helpers/A_TypeGuards.helper";
18
+ import { A_Error } from "../A-Error/A_Error.class";
19
+ import { A_FormatterHelper } from '@adaas/a-concept/helpers/A_Formatter.helper';
20
+ import { ASEID } from '../ASEID/ASEID.class';
21
+ import { A_CommonHelper } from '@adaas/a-concept/helpers/A_Common.helper';
22
+ import { A_TYPES__Entity_Constructor } from '../A-Entity/A-Entity.types';
23
+ import { A_ScopeError } from './A-Scope.error';
24
+ import { A_TYPES__Component_Constructor } from '../A-Component/A-Component.types';
25
+ import { A_TYPES__Fragment_Constructor } from '../A-Fragment/A-Fragment.types';
26
+ import { A_TYPES__Error_Constructor } from '../A-Error/A_Error.types';
27
+ import { A_TYPES__ComponentMetaKey } from '../A-Component/A-Component.constants';
17
28
 
18
- /**
19
- *
20
- *
21
- * A_Scope refers to the visibility and accessibility of :
22
- * - variables,
23
- * - Components,
24
- * - Context Fragments
25
- * - and objects in different parts of your code.
26
- * Scope determines where a particular piece of data (like a variable or function)
27
- * can be accessed, modified, or referenced, and it plays a crucial role in avoiding naming collisions and ensuring data integrity.
28
- *
29
- *
30
- */
31
- export class A_Scope {
32
29
 
33
- readonly name: string = '';
34
30
 
35
- private _components: WeakMap<typeof A_Component.constructor, any> = new WeakMap();
36
- private _fragments: WeakMap<typeof A_Fragment.constructor, any> = new WeakMap();
37
- private _commands: Map<string, A_Command> = new Map();
38
- private _entities: Map<string, A_Entity> = new Map();
39
31
 
40
- private _parent?: A_Scope;
32
+ export class A_Scope<
33
+ _ComponentType extends A_TYPES__Component_Constructor[] = A_TYPES__Component_Constructor[],
34
+ _ErrorType extends A_TYPES__Error_Constructor[] = A_TYPES__Error_Constructor[],
35
+ _EntityType extends A_TYPES__Entity_Constructor[] = A_TYPES__Entity_Constructor[],
36
+ _FragmentType extends A_Fragment[] = A_Fragment[],
37
+ > {
41
38
 
42
- protected params!: A_TYPES__ScopeConstructor
39
+ /**
40
+ * Scope Name uses for identification and logging purposes
41
+ */
42
+ protected _name!: string;
43
+ /**
44
+ * Parent scope reference, used for inheritance of components, fragments, entities and commands
45
+ */
46
+ protected _parent?: A_Scope;
43
47
 
48
+ // ===========================================================================
49
+ // --------------------ALLowed Constructors--------------------------------
50
+ // ===========================================================================
51
+ /**
52
+ * A set of allowed components, A set of constructors that are allowed in the scope
53
+ *
54
+ */
55
+ protected _allowedComponents = new Set<_ComponentType[number]>();
56
+ /**
57
+ * A set of allowed errors, A set of constructors that are allowed in the scope
58
+ */
59
+ protected _allowedErrors = new Set<_ErrorType[number]>();
60
+ /**
61
+ * A set of allowed entities, A set of constructors that are allowed in the scope
62
+ */
63
+ protected _allowedEntities = new Set<_EntityType[number]>();
64
+ /**
65
+ * A set of allowed fragments, A set of constructors that are allowed in the scope
66
+ */
67
+ protected _allowedFragments = new Set<A_TYPES__Fragment_Constructor<_FragmentType[number]>>();
44
68
 
45
- constructor(
46
- params: Partial<A_TYPES__ScopeConstructor>,
47
- config: Partial<A_TYPES__ScopeConfig> = {}
48
- ) {
49
- this.name = params.name || this.constructor.name;
50
69
 
51
- // TODO: move to defaults
52
- const defaultParams: A_TYPES__ScopeConstructor = {
53
- name: '',
54
- components: [],
55
- fragments: [],
56
- entities: [],
57
- commands: [],
58
- };
59
70
 
71
+ // ===========================================================================
72
+ // --------------------Internal Storage--------------------------------
73
+ // ===========================================================================
74
+ /**
75
+ * Storage for the components, should be strong as components are unique per scope
76
+ */
77
+ protected _components: Map<_ComponentType[number], InstanceType<_ComponentType[number]>> = new Map();
78
+ /**
79
+ * Storage for the errors, should be strong as errors are unique per code
80
+ */
81
+ protected _errors: Map<string, InstanceType<_ErrorType[number]>> = new Map();
82
+ /**
83
+ * Storage for the entities, should be strong as entities are unique per aseid
84
+ */
85
+ protected _entities: Map<string, InstanceType<_EntityType[number]>> = new Map();
86
+ /**
87
+ * Storage for the fragments, should be weak as fragments are singletons per scope
88
+ */
89
+ protected _fragments: Map<A_TYPES__Fragment_Constructor<_FragmentType[number]>, _FragmentType[number]> = new Map();
60
90
 
61
- this.params = {
62
- ...defaultParams,
63
- ...params
64
- }
65
91
 
66
- this.initComponents(params.components || []);
67
- this.initFragments(params.fragments || []);
68
- this.initEntities(params.entities || []);
69
92
 
70
- if (config.parent) {
71
- this._parent = config.parent;
72
- }
73
- }
74
93
 
94
+ // ===========================================================================
95
+ // --------------------Readonly Allowed Properties----------------------------
96
+ // ===========================================================================
97
+ /**
98
+ * Returns the name of the scope
99
+ */
100
+ get name() { return this._name }
75
101
 
76
- private initComponents(_components: Array<{ new(...args: any[]): any }>) {
77
- // _components.forEach(component => {
78
- // this._components.set(component, new component());
79
- // })
80
- }
102
+ /**
103
+ * Returns a list of Constructors for A-Components that are available in the scope
104
+ */
105
+ get allowedComponents() { return this._allowedComponents }
106
+ /**
107
+ * Returns a list of Constructors for A-Entities that are available in the scope
108
+ */
109
+ get allowedEntities() { return this._allowedEntities }
110
+ /**
111
+ * Returns a list of Constructors for A-Fragments that are available in the scope
112
+ */
113
+ get allowedFragments() { return this._allowedFragments }
114
+ /**
115
+ * Returns a list of Constructors for A-Errors that are available in the scope
116
+ */
117
+ get allowedErrors() { return this._allowedErrors }
118
+ // ===========================================================================
119
+ // --------------------Readonly Registered Properties--------------------------
120
+ // ===========================================================================
121
+ /**
122
+ * Returns an Array of entities registered in the scope
123
+ *
124
+ * [!] One entity per aseid
125
+ */
126
+ get entities(): Array<InstanceType<_EntityType[number]>> { return Array.from(this._entities.values()) }
127
+ /**
128
+ * Returns an Array of fragments registered in the scope
129
+ *
130
+ * [!] One fragment per scope
131
+ */
132
+ get fragments(): Array<_FragmentType[number]> { return Array.from(this._fragments.values()) }
133
+ /**
134
+ * Returns an Array of components registered in the scope
135
+ *
136
+ * [!] One component instance per scope
137
+ */
138
+ get components(): Array<InstanceType<_ComponentType[number]>> { return Array.from(this._components.values()) }
81
139
 
82
- private initEntities(_entities: Array<A_Entity>) {
83
- _entities.forEach(this.register.bind(this));
140
+ /**
141
+ * Returns the parent scope of the current scope
142
+ *
143
+ * @param setValue
144
+ * @returns
145
+ */
146
+ get parent(): A_Scope | undefined {
147
+ return this._parent;
84
148
  }
85
-
86
-
87
- private initFragments(_fragments: Array<A_Fragment>) {
88
- _fragments.forEach(this.register.bind(this));
149
+ /**
150
+ * A_Scope refers to the visibility and accessibility of :
151
+ * - variables,
152
+ * - Components,
153
+ * - Context Fragments
154
+ * - Entities
155
+ * - and objects in different parts of your code.
156
+ * Scope determines where a particular piece of data (like a variable or function)
157
+ * can be accessed, modified, or referenced, and it plays a crucial role in avoiding naming collisions and ensuring data integrity.
158
+ *
159
+ * [!] The scope behavior is similar to tree structure where each scope can have a parent scope and inherit its components, fragments, entities and errors
160
+ *
161
+ * @param params
162
+ * @param config
163
+ */
164
+ constructor()
165
+ constructor(
166
+ /**
167
+ * A set of constructors that are allowed in the scope
168
+ */
169
+ params: Partial<A_TYPES__Scope_Init<_ComponentType, _ErrorType, _EntityType, _FragmentType>>,
170
+ /**
171
+ * Configuration options for the scope
172
+ */
173
+ config?: Partial<A_TYPES__ScopeConfig>
174
+ )
175
+ constructor(
176
+ param1?: Partial<A_TYPES__Scope_Init<_ComponentType, _ErrorType, _EntityType, _FragmentType>>,
177
+ param2?: Partial<A_TYPES__ScopeConfig>
178
+ ) {
179
+ const initializer = this.getInitializer(param1);
180
+ // the returned initializer is already bound to `this` (we used .bind(this)),
181
+ // so calling it will run the appropriate logic on this instance:
182
+ initializer.call(this, param1, param2);
89
183
  }
90
184
 
91
185
 
92
- get components() {
93
- return this.params.components || [];
94
- }
95
186
 
96
- get commands() {
97
- return this.params.commands || [];
98
- }
187
+ /**
188
+ * Determines which initializer method to use based on the type of the first parameter.
189
+ *
190
+ * @param param1
191
+ * @returns
192
+ */
193
+ protected getInitializer(
194
+ param1?: Partial<A_TYPES__Scope_Init<_ComponentType, _ErrorType, _EntityType, _FragmentType>>,
195
+ param2?: Partial<A_TYPES__ScopeConfig>
196
+ ): (param1: any, param2: any) => void | (() => void) {
197
+ switch (true) {
198
+ case !param1 && !param2: ;
199
+ return this.defaultInitialized;
99
200
 
100
- get fragments() {
101
- return this.params.fragments || [];
201
+ case !!param1:
202
+ return this.defaultInitialized;
203
+ default:
204
+ throw new A_ScopeError(A_ScopeError.ConstructorError, 'Invalid parameters provided to A_Scope constructor');
205
+ }
102
206
  }
103
207
 
104
208
 
105
- parent(setValue: A_Scope): void
106
- parent(): A_Scope
107
- parent(
108
- setValue?: A_Scope
109
- ): A_Scope | undefined {
110
- if (setValue) {
111
- return this.inherit(setValue);
112
- }
113
209
 
114
- return this._parent;
115
- }
210
+ protected defaultInitialized(
211
+ params: Partial<A_TYPES__Scope_Init<_ComponentType, _ErrorType, _EntityType, _FragmentType>> = {},
212
+ config: Partial<A_TYPES__ScopeConfig> = {}
213
+ ) {
214
+ this._name = params.name || this.constructor.name
116
215
 
117
- isInheritedFrom(scope: A_Scope): boolean {
118
- let current: A_Scope | undefined = this;
216
+ this.initComponents(params.components);
217
+ this.initErrors(params.errors);
218
+ this.initFragments(params.fragments);
219
+ this.initEntities(params.entities);
119
220
 
120
- while (current) {
121
- if (current === scope) {
122
- return true;
123
- }
124
- current = current._parent;
221
+ if (config.parent) {
222
+ this._parent = config.parent;
125
223
  }
126
-
127
- return false;
128
224
  }
129
225
 
130
226
 
131
- inherit(parent: A_Scope): A_Scope {
132
- // Prevent circular inheritance
133
- const circularCheck = this.checkCircularInheritance(parent);
227
+ //==========================================================================
228
+ // --------------------Scope Initialization Methods---------------------------
229
+ //==========================================================================
134
230
 
135
- if (circularCheck) {
136
- throw new Error(`Circular inheritance detected: ${[...circularCheck, parent.name].join(' -> ')}`);
137
- }
231
+ /**
232
+ * This method is used to initialize the components in the scope
233
+ * To save memory components are initialized only when they are requested
234
+ *
235
+ * This method only registers the component in the scope in case they are not registered yet
236
+ *
237
+ * @param _components
238
+ */
239
+ protected initComponents(_components?: _ComponentType) { _components?.forEach(this.register.bind(this)); }
240
+ /**
241
+ * This method is used to initialize the errors in the scope
242
+ *
243
+ * This method only registers the errors in the scope in case they are not registered yet
244
+ *
245
+ * @param _errors
246
+ */
247
+ protected initErrors(_errors?: _ErrorType) { _errors?.forEach(this.register.bind(this)); }
248
+ /**
249
+ * This method is used to initialize the entities in the scope
250
+ *
251
+ * This method only registers the entities in the scope in case they are not registered yet
252
+ *
253
+ * @param _entities
254
+ */
255
+ protected initEntities(_entities?: [
256
+ ..._EntityType,
257
+ ...InstanceType<_EntityType[number]>[]
258
+ ]) { _entities?.forEach(ent => this.register(ent as any)); }
259
+ /**
260
+ * This method is used to initialize the fragments in the scope
261
+ *
262
+ * This method only registers the fragments in the scope in case they are not registered yet
263
+ *
264
+ * @param _fragments
265
+ */
266
+ protected initFragments(_fragments?: _FragmentType) { _fragments?.forEach(this.register.bind(this)); }
138
267
 
139
- this._parent = parent;
140
- return this;
268
+
269
+ /**
270
+ * Returns the issuer of the scope, useful for debugging and tracking purposes
271
+ *
272
+ * Issuer can be:
273
+ * - A Container that allocated the scope
274
+ * - A Feature that allocated the scope
275
+ *
276
+ * [!] Note that the issuer is the direct allocator of the scope, so if a Container allocated a Feature that allocated the scope, the issuer will be the Feature
277
+ *
278
+ * @returns
279
+ */
280
+ issuer<T extends A_TYPES__ScopeLinkedComponents>(): T {
281
+ return A_Context.issuer(this) as T;
141
282
  }
142
283
 
143
284
 
144
285
 
145
286
  /**
146
- * Helper method to check circular inheritance
147
- * Should return a full sequence of inheritance for logging purposes
287
+ * This method is used to inherit from a parent scope
148
288
  *
149
- * @param scope
289
+ * [!] This method checks for circular inheritance and throws an error if detected
290
+ *
291
+ * @param parent
150
292
  * @returns
151
293
  */
152
- checkCircularInheritance(scope: A_Scope): Array<string> | false {
153
- const inheritanceChain: Array<string> = [];
154
- let current: A_Scope | undefined = this._parent;
294
+ inherit(parent: A_Scope): A_Scope {
295
+ if (!parent)
296
+ throw new A_ScopeError(
297
+ A_ScopeError.InitializationError,
298
+ `Invalid parent scope provided`
299
+ );
155
300
 
156
- while (current) {
157
- inheritanceChain.push(current.name);
158
- if (current === scope) {
159
- return inheritanceChain;
160
- }
161
- current = current._parent;
162
- }
301
+ if (parent === this)
302
+ throw new A_ScopeError(
303
+ A_ScopeError.CircularInheritanceError,
304
+ `Unable to inherit scope ${this.name} from itself`
305
+ );
163
306
 
164
- return false;
165
- }
307
+ if (parent === this._parent)
308
+ return this;
166
309
 
310
+ // Prevent circular inheritance
311
+ const circularCheck = this.checkCircularInheritance(parent);
167
312
 
168
- printInheritanceChain(): void {
169
- const chain: Array<string> = [];
170
- let current: A_Scope | undefined = this;
313
+ if (circularCheck)
314
+ throw new A_ScopeError(
315
+ A_ScopeError.CircularInheritanceError,
316
+ `Circular inheritance detected: ${[...circularCheck, parent.name].join(' -> ')}`
317
+ );
171
318
 
172
- while (current) {
173
- chain.push(current.name);
174
- current = current._parent;
175
- }
176
319
 
177
- console.log(chain.join(' -> '));
320
+ this._parent = parent;
321
+ return this;
178
322
  }
179
323
 
180
324
 
181
325
  /**
182
326
  * This method is used to check if the component is available in the scope
183
327
  *
328
+ * [!] Note that this method checks for the component in the current scope and all parent scopes
329
+ *
184
330
  * @param component
185
331
  * @returns
186
332
  */
187
333
  has<T extends A_Component>(
188
- component: new (...args: any[]) => T
334
+ /**
335
+ * Provide a component constructor to check if it's available in the scope
336
+ */
337
+ component: A_TYPES__Component_Constructor<T>
189
338
  ): boolean
190
339
  has<T extends A_Entity>(
191
- entity: new (...args: any[]) => T
340
+ /**
341
+ * Provide an entity constructor to check if it's available in the scope
342
+ *
343
+ * [!] Note that entities are unique per aseid, so this method checks if there's at least one entity of the provided type in the scope
344
+ */
345
+ entity: A_TYPES__Entity_Constructor<T>
192
346
  ): boolean
193
347
  has<T extends A_Fragment>(
194
- fragment: new (...args: any[]) => T
348
+ /**
349
+ * Provide a fragment constructor to check if it's available in the scope
350
+ */
351
+ fragment: A_TYPES__Fragment_Constructor<T>
195
352
  ): boolean
196
353
  has(
354
+ /**
355
+ * Provide a string to check if a component, entity or fragment with the provided name is available in the scope
356
+ */
197
357
  constructor: string
198
358
  ): boolean
199
- has<T extends A_Fragment | A_Component | A_Entity | A_Command>(
200
- entity: T | string | (new (...args: any[]) => T)
359
+ has(
360
+ ctor: unknown
201
361
  ): boolean {
202
362
 
363
+ let found = false;
203
364
 
204
365
  switch (true) {
366
+ // 1) Check by string name.
367
+ case typeof ctor === 'string': {
368
+ // 1.1 Check if it's a component name
369
+ const possibleComponent = Array.from(this.allowedComponents).find(c => c.name === ctor);
370
+ if (possibleComponent) found = true;
205
371
 
206
- case typeof entity === 'string': {
207
- const possibleComponent = this.params.components.find(c => c.name === entity);
208
-
209
- if (possibleComponent) {
210
- return true;
211
- }
212
-
213
- const possibleFragment = this.params.fragments.find(f => f.name === entity);
214
-
215
- if (possibleFragment) {
216
- return true;
217
- }
372
+ // 1.2 Check if it's a fragment name
373
+ const possibleFragment = Array.from(this.allowedFragments).find(f => f.name === ctor);
374
+ if (possibleFragment) found = true;
218
375
 
219
- if (this.params.entities.some(e => e.constructor.name === entity)) {
220
- return true;
221
- }
376
+ // 1.4 Check if it's an entity name or entity static entity property
377
+ const possibleEntity = Array.from(this.allowedEntities).find(e => e.name === ctor);
378
+ if (possibleEntity) found = true;
222
379
 
380
+ // 1.5 If not found in current scope, check parent scope
223
381
  if (!!this._parent)
224
- return this._parent.has(entity);
382
+ return this._parent.has(ctor);
225
383
 
226
384
  return false;
227
385
  }
386
+ // 2) Check if it's a Component
387
+ case A_TypeGuards.isComponentConstructor(ctor): {
388
+ found = this.isAllowedComponent(ctor);
228
389
 
229
- case typeof entity === 'function'
230
- && A_CommonHelper.isInheritedFrom(entity, A_Component): {
231
- const found = this.components.includes(entity as { new(...args: any[]): A_Component });
232
-
233
- if (!found && !!this._parent) {
234
- return this._parent.has(entity as any);
235
- }
236
-
237
- return found;
238
- }
239
-
240
- case typeof entity === 'function'
241
- && A_CommonHelper.isInheritedFrom(entity, A_Entity): {
242
- const entities = Array.from(this._entities.values());
243
-
244
- const found = entities.find(e => e instanceof entity);
245
-
246
- return !!found;
247
- }
248
-
249
- case typeof entity === 'function'
250
- && A_CommonHelper.isInheritedFrom(entity, A_Fragment): {
251
- const found = this._fragments.has(entity);
252
-
253
- if (!found && !!this._parent)
254
- return this._parent.has(entity as any);
390
+ break;
391
+ }
392
+ // 3) Check if it's an Entity
393
+ case A_TypeGuards.isEntityConstructor(ctor): {
394
+ found = this.isAllowedEntity(ctor);
255
395
 
256
- return found;
257
- }
258
- case typeof entity === 'function'
259
- && A_CommonHelper.isInheritedFrom(entity, A_Command): {
260
- const found = this.commands.includes(entity as { new(...args: any[]): A_Command });
396
+ break;
397
+ }
398
+ // 4) Check if it's a Fragment
399
+ case A_TypeGuards.isFragmentConstructor(ctor): {
400
+ found = this.isAllowedFragment(ctor);
261
401
 
262
- if (!found && !!this._parent)
263
- return this._parent.has(entity as any);
402
+ break;
403
+ }
404
+ }
264
405
 
265
- return found;
266
- }
406
+ if (!found && !!this._parent)
407
+ return this._parent.has(ctor as any);
267
408
 
268
409
 
269
- default: {
270
- return false;
271
- }
272
- }
410
+ return found;
273
411
  }
274
412
 
275
413
 
@@ -286,19 +424,14 @@ export class A_Scope {
286
424
  merge(anotherScope: A_Scope): A_Scope {
287
425
  const merged = new A_Scope(
288
426
  {
289
- name: `${this.name}&${anotherScope.name}`,
290
- components: Array.from(new Set([
291
- ...this.params.components,
292
- ...anotherScope.params.components
293
- ])),
294
- fragments: Array.from(new Set([
295
- ...this.params.fragments,
296
- ...anotherScope.params.fragments
297
- ])),
298
- entities: Array.from(new Set([
299
- ...this.params.entities,
300
- ...anotherScope.params.entities
301
- ])),
427
+ name: `${this.name} + ${anotherScope.name}`,
428
+
429
+ components: [...this.allowedComponents, ...anotherScope.allowedComponents],
430
+ fragments: [...this.fragments, ...anotherScope.fragments],
431
+ entities: [
432
+ ...this.entities, ...anotherScope.entities,
433
+ ...this.allowedEntities, ...anotherScope.allowedEntities
434
+ ],
302
435
  },
303
436
  {
304
437
  parent: this._parent || anotherScope._parent
@@ -314,34 +447,55 @@ export class A_Scope {
314
447
  *
315
448
  * [!] Notes:
316
449
  * - In case of search for A-Entity please ensure that provided string corresponds to the static entity property of the class. [!] By default it's the kebab-case of the class name
317
- * - In case of search for A_Command please ensure that provided string corresponds to the static code property of the class. [!] By default it's the kebab-case of the class name
318
450
  * - In case of search for A_Component please ensure that provided string corresponds to the class name in PascalCase
319
451
  *
320
452
  * @param name
321
453
  * @returns
322
454
  */
323
- resolveConstructor<T extends A_Component | A_Entity>(name: string): new (...args: any[]) => T {
324
- // Check components
325
- const component = this.params.components.find(c => c.name === A_CommonHelper.toPascalCase(name));
326
- if (component) return component as any;
327
-
328
- // Check entities
329
- const entity = this.params.entities.find(e => (e.constructor as any).entity === name
330
- || (e.constructor as any).name === A_CommonHelper.toPascalCase(name)
331
- || (e.constructor as any).entity === A_CommonHelper.toKebabCase(name)
455
+ resolveConstructor<T extends A_Entity>(
456
+ /**
457
+ * Provide the entity name or static entity property to retrieve its constructor
458
+ */
459
+ name: string
460
+ ): A_TYPES__Entity_Constructor<T>
461
+ resolveConstructor<T extends A_Component>(
462
+ /**
463
+ * Provide the component name in PascalCase to retrieve its constructor
464
+ */
465
+ name: string
466
+ ): A_TYPES__Component_Constructor<T>
467
+ resolveConstructor<T extends A_Fragment>(
468
+ /**
469
+ * Provide the fragment name in PascalCase to retrieve its constructor
470
+ */
471
+ name: string
472
+ ): A_TYPES__Fragment_Constructor<T>
473
+ resolveConstructor<T extends A_TYPES__ScopeResolvableComponents>(name: string): A_TYPES__Entity_Constructor<T> | A_TYPES__Component_Constructor<T> | A_TYPES__Fragment_Constructor<T> {
474
+ // 1) Check components
475
+ const component = Array.from(this.allowedComponents).find(
476
+ c => c.name === name
477
+ || c.name === A_FormatterHelper.toPascalCase(name)
478
+ );
479
+ if (component) return component as A_TYPES__Component_Constructor<T>;
480
+
481
+ // 2) Check entities
482
+ const entity = Array.from(this.allowedEntities).find(
483
+ e => e.name === name
484
+ || e.name === A_FormatterHelper.toPascalCase(name)
485
+ || (e as any).entity === name
486
+ || (e as any).entity === A_FormatterHelper.toKebabCase(name)
332
487
  );
333
- if (entity) return entity.constructor as any;
488
+ if (entity) return entity as A_TYPES__Entity_Constructor<T>;
334
489
 
335
- // Check commands
336
- const command = this.params.commands.find(c => (c as any).code === name
337
- || (c as any).name === A_CommonHelper.toPascalCase(name)
338
- || (c as any).code === A_CommonHelper.toKebabCase(name)
490
+ // 3) Check fragments
491
+ const fragment = Array.from(this.allowedFragments).find(f => f.name === name
492
+ || f.name === A_FormatterHelper.toPascalCase(name)
339
493
  );
340
- if (command) return command as any;
494
+ if (fragment) return fragment as A_TYPES__Fragment_Constructor<T>;
341
495
 
342
496
  // If not found in current scope, check parent scope
343
497
  if (!!this._parent) {
344
- return this._parent.resolveConstructor(name);
498
+ return this._parent.resolveConstructor(name) as any;
345
499
  }
346
500
 
347
501
  throw new Error(`Component or Entity with name ${name} not found in the scope ${this.name}`);
@@ -349,135 +503,224 @@ export class A_Scope {
349
503
 
350
504
 
351
505
 
352
-
353
-
354
506
  /**
355
- * This method is used to get the component by class
507
+ * This method allows to resolve/inject a component, fragment or entity from the scope
508
+ * Depending on the provided parameters it can resolve:
509
+ * - A single component/fragment/entity by its constructor or name
510
+ * - An array of components/fragments/entities by providing an array of constructors
511
+ * - An entity or an array of entities by providing the entity constructor and query instructions
356
512
  *
357
513
  * @param component
358
514
  * @returns
359
515
  */
360
- resolve<T extends A_TYPES__A_InjectDecorator_Injectable>(
361
- string: string
362
- ): InstanceType<T>
363
- resolve<T extends A_TYPES__A_InjectDecorator_Injectable>(
364
- component: T
365
- ): InstanceType<T>
516
+ resolve<T extends A_Component>(
517
+ /**
518
+ * Provide a component constructor to resolve its instance from the scope
519
+ */
520
+ component: A_TYPES__Component_Constructor<T>
521
+ ): T
522
+ resolve<T extends A_TYPES__Component_Constructor[]>(
523
+ /**
524
+ * Provide an array of component constructors to resolve their instances from the scope
525
+ */
526
+ components: [...T]
527
+ ): Array<InstanceType<T[number]>>
528
+ resolve<T extends A_Fragment>(
529
+ /**
530
+ * Provide a fragment constructor to resolve its instance from the scope
531
+ */
532
+ fragment: A_TYPES__Fragment_Constructor<T>
533
+ ): T
534
+ resolve<T extends A_TYPES__Fragment_Constructor[]>(
535
+ /**
536
+ * Provide an array of fragment constructors to resolve their instances from the scope
537
+ */
538
+ fragments: [...T]
539
+ ): Array<InstanceType<T[number]>>
540
+ resolve<T extends A_Entity>(
541
+ /**
542
+ * Provide an entity constructor to resolve its instance or an array of instances from the scope
543
+ */
544
+ entity: A_TYPES__Entity_Constructor<T>
545
+ ): T | undefined
546
+ resolve<T extends A_Scope>(
547
+ /**
548
+ * Uses only in case of resolving a single entity
549
+ *
550
+ * Provide an entity constructor to resolve its instance from the scope
551
+ */
552
+ scope: new (...args: any[]) => T
553
+ ): T
366
554
  resolve<T extends A_Entity>(
367
- entity: { new(...args: any[]): T },
555
+ /**
556
+ * Provide an entity constructor to resolve its instance or an array of instances from the scope
557
+ */
558
+ entity: A_TYPES__Entity_Constructor<T>,
559
+ /**
560
+ * Provide optional instructions to find a specific entity or a set of entities
561
+ */
368
562
  instructions: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions<T>>
369
- ): T | Array<T>
370
- resolve<T extends A_TYPES__A_InjectDecorator_Injectable>(
371
- component: Array<T>
372
- ): Array<InstanceType<T>>
563
+ ): Array<T>
564
+ resolve(
565
+ constructorName: string
566
+ ): A_TYPES__ScopeResolvableComponents
373
567
  // base definition
374
- resolve<T extends A_TYPES__A_InjectDecorator_Injectable>(
375
- param1: Array<T> | T | string,
376
- param2?: string | Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions>
377
- ): Array<InstanceType<T>> | InstanceType<T> {
378
-
568
+ resolve<T extends A_TYPES__ScopeResolvableComponents>(
569
+ /**
570
+ * Provide a component, fragment or entity constructor or an array of constructors to resolve its instance(s) from the scope
571
+ */
572
+ param1: A_TYPES__InjectableConstructors,
379
573
 
574
+ ): T | Array<T>
575
+ resolve<T extends A_TYPES__ScopeResolvableComponents>(
576
+ /**
577
+ * Provide a component, fragment or entity constructor or an array of constructors to resolve its instance(s) from the scope
578
+ */
579
+ param1: A_TYPES__InjectableConstructors | Array<A_TYPES__InjectableConstructors>,
580
+ param2?: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions>
581
+ ): T | Array<T> {
380
582
  switch (true) {
381
- case Array.isArray(param1): {
382
- return param1.map(c => this.resolveOnce(param1 as any, param2 as any));
583
+ case A_TypeGuards.isArray(param1): {
584
+ return param1.map(c => {
585
+ if (A_TypeGuards.isString(c))
586
+ return this.resolveByName(c);
587
+ else
588
+ return this.resolveOnce(c, param2);
589
+ }).filter(Boolean) as Array<T>;
383
590
  }
384
591
 
385
- case typeof param1 === 'function': {
386
- return this.resolveOnce(param1 as any, param2 as any);
592
+ case A_TypeGuards.isFunction(param1): {
593
+ return this.resolveOnce(param1, param2);
387
594
  }
388
595
 
389
- case typeof param1 === 'string': {
390
- return this.resolveByName(param1 as any) as InstanceType<T>;
596
+ case A_TypeGuards.isString(param1): {
597
+ return this.resolveByName(param1) as T;
391
598
  }
392
599
 
393
600
  default: {
394
- throw new Error('Invalid arguments provided');
601
+ throw new A_Error(`Invalid parameter provided to resolve method: ${param1} in scope ${this.name}`);
395
602
  }
396
603
  }
397
604
  }
398
605
 
399
606
 
400
- private resolveByName(name: string): A_Entity | A_Fragment | A_Component {
401
- // Check components
402
- const component = this.params.components.find(c => c.name === name);
403
- if (component) return this.resolveComponent(component);
404
607
 
405
- // Check commands
406
- const command = this.params.commands.find(c => c.name === name);
407
- if (command) return this.resolveComponent(command);
408
608
 
409
- // Check fragments
410
- const fragment = this.params.fragments.find(f => f.constructor.name === name);
411
- if (fragment) return this.resolveFragment(fragment.constructor as any);
609
+ // ==================================================================================================
610
+ // --------------------------------------------------------------------------------------------------
611
+ // -------------------------------------INTERNAL RESOLVERS-------------------------------------------
612
+ // --------------------------------------------------------------------------------------------------
613
+ // ==================================================================================================
614
+ /**
615
+ * This method is used internally to resolve a component, fragment or entity by its constructor name
616
+ *
617
+ * [!] Note that this method checks for the component, fragment or entity in the current scope and all parent scopes
618
+ *
619
+ * @param name - name of the component, fragment or entity to resolve (constructor name for components and fragments, static entity property for entities, static code property for commands)
620
+ * @returns
621
+ */
622
+ private resolveByName(
623
+ /**
624
+ * Provide the name of the component, fragment or entity to resolve
625
+ */
626
+ name: string
627
+ ): _EntityType[number] | InstanceType<_ComponentType[number]> | _FragmentType[number] {
628
+ // 1) Check components
629
+ const component = Array.from(this.allowedComponents).find(
630
+ c => c.name === name
631
+ || c.name === A_FormatterHelper.toPascalCase(name)
632
+ );
633
+ if (component) return this.resolveOnce(component) as InstanceType<_ComponentType[number]>;
634
+
635
+ // 2) Check entities
636
+ const entity = Array.from(this.allowedEntities).find(
637
+ e => e.name === name
638
+ || e.name === A_FormatterHelper.toPascalCase(name)
639
+ || (e as any).entity === name
640
+ || (e as any).entity === A_FormatterHelper.toKebabCase(name)
641
+ );
642
+ if (entity) return this.resolveOnce(entity) as InstanceType<_EntityType[number]>;
412
643
 
413
- // Check entities
414
- const entity = this.params.entities.find(e => e.constructor.name === name);
415
- if (entity) return this.resolveEntity(entity.constructor as any);
644
+ // 3) Check fragments
645
+ const fragment = Array.from(this.allowedFragments).find(f => f.name === name
646
+ || f.name === A_FormatterHelper.toPascalCase(name)
647
+ );
648
+ if (fragment) return this.resolveOnce(fragment) as _FragmentType[number];
416
649
 
417
650
  // If not found in current scope, check parent scope
418
- if (this._parent) {
419
- return this._parent.resolveByName(name);
651
+ if (!!this._parent) {
652
+ return this._parent.resolveByName(name) as any;
420
653
  }
421
654
 
422
- throw new Error(`Component, Fragment, or Entity with name ${name} not found in the scope ${this.name}`);
655
+ throw new Error(`Component or Entity with name ${name} not found in the scope ${this.name}`);
423
656
  }
424
657
 
425
-
426
-
427
-
428
- private resolveOnce<T extends { new(...args: any[]): A_Entity }>(
429
- entity: T,
430
- instructions: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions>
431
- ): InstanceType<T> | undefined
432
- private resolveOnce<T extends A_TYPES__A_InjectDecorator_Injectable>(
433
- component: T
434
- ): InstanceType<T>
435
- private resolveOnce<T extends { new(...args: any[]): A_Entity } | A_TYPES__A_InjectDecorator_Injectable>(
436
- component: T,
658
+ /**
659
+ * This method is used internally to resolve a single component, fragment or entity from the scope
660
+ *
661
+ * @param component
662
+ * @param instructions
663
+ * @returns
664
+ */
665
+ private resolveOnce<T extends A_Component | A_Fragment | A_Entity | A_Scope>(
666
+ component: unknown,
437
667
  instructions?: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions>
438
- ): InstanceType<T> {
668
+ ): T | Array<T> {
669
+
670
+ if (A_TypeGuards.isScopeConstructor(component))
671
+ component
439
672
 
673
+ if (typeof component == 'function' && (component as any).name === 'A_Scope')
674
+ component
440
675
 
441
676
  switch (true) {
442
- case A_CommonHelper.isInheritedFrom(component, A_Entity): {
443
- return this.resolveEntity(component as any, instructions) as InstanceType<T>;
677
+ case A_TypeGuards.isEntityConstructor(component): {
678
+ return this.resolveEntity(component, instructions) as T | Array<T>;
444
679
  }
445
-
446
- case A_CommonHelper.isInheritedFrom(component, A_Fragment): {
447
- return this.resolveFragment(component as typeof A_Fragment) as InstanceType<T>;
680
+ case A_TypeGuards.isFragmentConstructor(component): {
681
+ return this.resolveFragment(component) as T;
448
682
  }
449
-
450
- case A_CommonHelper.isInheritedFrom(component, A_Scope): {
451
- return this.resolveScope(component as typeof A_Scope) as InstanceType<T>;
683
+ case A_TypeGuards.isScopeConstructor(component): {
684
+ return this.resolveScope(component) as T;
452
685
  }
453
-
454
- case A_CommonHelper.isInheritedFrom(component, A_Component): {
455
- return this.resolveComponent(component as typeof A_Component) as InstanceType<T>;
686
+ case A_TypeGuards.isComponentConstructor(component): {
687
+ return this.resolveComponent(component) as T;
456
688
  }
457
-
458
689
  default:
459
690
  throw new Error(`Injected Component ${component} not found in the scope`);
460
691
  }
461
692
  }
462
693
 
694
+ /**
695
+ * This method is used internally to resolve a single entity from the scope based on the provided instructions
696
+ *
697
+ * [!] Note that this method can return either a single entity or an array of entities depending on the instructions provided
698
+ *
699
+ * @param entity
700
+ * @param instructions
701
+ * @returns
702
+ */
703
+ private resolveEntity<T extends A_Entity>(
704
+ entity: A_TYPES__Entity_Constructor<T>,
705
+ instructions?: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions<T>>
706
+ ): T | Array<T> | undefined {
463
707
 
464
- private resolveEntity<T extends { new(...args: any[]): A_Entity }>(
465
- entity: T,
466
- instructions?: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions<InstanceType<T>>>
467
- ): InstanceType<T> | undefined | InstanceType<T>[] {
468
-
469
- const query = instructions?.query || {} as Partial<A_TYPES__A_InjectDecorator_EntityInjectionQuery<InstanceType<T>>>;
708
+ const query = instructions?.query || {} as Partial<A_TYPES__A_InjectDecorator_EntityInjectionQuery<T>>;
470
709
  const count = instructions?.pagination?.count || 1;
471
710
 
472
711
  switch (true) {
712
+ /**
713
+ * 1) In case when no instructions provided, return the first found entity of the provided type
714
+ *
715
+ * [!] Note that it returns ONLY ONE entity
716
+ * [!!] In case when no entity found in the current scope, it tries to resolve it from the parent scope (if exists)
717
+ */
473
718
  case !instructions: {
474
- const entities = Array.from(this._entities.values());
475
-
476
- const found = entities.find(e => e instanceof entity);
719
+ const found = this.entities.find(e => e instanceof entity);
477
720
 
478
721
  switch (true) {
479
722
  case !!found:
480
- return found as InstanceType<T>;
723
+ return found as T;
481
724
 
482
725
  case !found && !!this._parent:
483
726
  return this._parent.resolveEntity(entity, instructions);
@@ -486,74 +729,84 @@ export class A_Scope {
486
729
  throw new Error(`Entity ${entity.name} not found in the scope ${this.name}`);
487
730
  }
488
731
  }
489
-
732
+ /**
733
+ * 2) In case when aseid is provided in the query, we can directly get the entity from the map
734
+ *
735
+ * [!] Note that it returns ONLY ONE entity
736
+ */
490
737
  case !!query.aseid
491
738
  && typeof query.aseid === 'string'
492
739
  && this._entities.has(query.aseid): {
493
- return this._entities.get(query.aseid) as InstanceType<T>;
740
+ return this._entities.get(query.aseid) as T;
494
741
  }
495
-
742
+ /**
743
+ * 3) In case when aseid is provided as ASEID instance, we can directly get the entity from the map
744
+ *
745
+ * [!] Note that it returns ONLY ONE entity
746
+ */
496
747
  case !!query.aseid
497
748
  && typeof query.aseid === 'object'
498
749
  && query.aseid instanceof ASEID
499
750
  && this._entities.has(query.aseid.toString()): {
500
- return this._entities.get(query.aseid.toString()) as InstanceType<T>;
751
+ return this._entities.get(query.aseid.toString()) as T;
501
752
  }
502
-
753
+ /**
754
+ * 4) In case when id is provided in the query, we have to find the entity by the id
755
+ *
756
+ * [!] Note that it returns ONLY ONE entity
757
+ */
503
758
  case !!query.id: {
504
759
 
505
- // in this case we have to find the entity by the id
506
- const entities = Array.from(this._entities.values());
507
-
508
- const found = entities.filter(
509
- e => e instanceof entity
510
- ).find(e => {
511
- return String(e.id) === String(query.id)
512
- });
760
+ const found = this.entities
761
+ .filter(e => e instanceof entity)
762
+ .find(e => String(e.id) === String(query.id));
513
763
 
514
- return found as InstanceType<T>;
764
+ return found as T;
515
765
  }
516
-
766
+ /**
767
+ * 5) In case when there's a query object, we have to filter the entities by the query
768
+ *
769
+ * [!] Note that it can return either a single entity or an array of entities depending on the count instruction
770
+ * [!!] In case when no entity found in the current scope, it tries to resolve it from the parent scope (if exists)
771
+ */
517
772
  default: {
518
- const entities = Array.from(this._entities.values());
519
-
520
- const found = entities.filter(
521
- e => e instanceof entity
522
- ).filter(e => {
523
- return Object.entries(query).every(([key, value]) => {
524
- if (key in e) {
525
- return (e as any)[key] === value;
526
- }
527
- return false;
773
+
774
+ const found = this.entities
775
+ .filter(e => e instanceof entity)
776
+ .filter(e => {
777
+ return Object
778
+ .entries(query)
779
+ .every(([key, value]) => {
780
+ if (key in e) {
781
+ return (e as any)[key] === value;
782
+ }
783
+ return false;
784
+ });
528
785
  });
529
- });
530
786
 
531
787
  if (found.length === 0 && !!this._parent)
532
788
  return this._parent.resolveEntity(entity, instructions);
533
789
 
534
790
  if (count === 1)
535
- return found[0] as InstanceType<T>;
791
+ return found[0] as T;
536
792
 
537
- return found as InstanceType<T>[];
793
+ return found as T[];
538
794
  }
539
-
540
795
  }
541
796
  }
542
797
 
543
-
544
-
545
- private resolveFragment<T extends typeof A_Fragment>(fragment: T): InstanceType<T> {
546
-
547
- const fragmentInstancePresented = this.fragments.some(fr => fr instanceof fragment);
548
-
798
+ /**
799
+ * This method is used internally to resolve a single fragment from the scope
800
+ *
801
+ * @param fragment
802
+ * @returns
803
+ */
804
+ private resolveFragment<T extends A_Fragment>(fragment: A_TYPES__Fragment_Constructor<T>): _FragmentType[number] {
805
+ const fragmentInstancePresented = this._fragments.get(fragment);
549
806
 
550
807
  switch (true) {
551
-
552
808
  case fragmentInstancePresented && this._fragments.has(fragment):
553
- return this._fragments.get(fragment);
554
-
555
- case fragmentInstancePresented && !this._fragments.has(fragment):
556
- return this.fragments.find(fr => fr instanceof fragment) as InstanceType<T>;
809
+ return fragmentInstancePresented;
557
810
 
558
811
  case !fragmentInstancePresented && !!this._parent:
559
812
  return this._parent.resolveFragment(fragment);
@@ -562,28 +815,34 @@ export class A_Scope {
562
815
  throw new Error(`Fragment ${fragment.name} not found in the scope ${this.name}`);
563
816
  }
564
817
  }
565
-
566
-
567
- private resolveScope(scope: typeof A_Scope): A_Scope {
818
+ /**
819
+ * This method is used internally to resolve a single scope from the current scope
820
+ *
821
+ * @param scope
822
+ * @returns
823
+ */
824
+ private resolveScope(scope: A_TYPES__Scope_Constructor): A_Scope {
568
825
  return this;
569
826
  }
570
-
571
-
572
- private resolveComponent<T extends A_Component>(component: {
573
- new(...args: any[]): T
574
- }): T {
827
+ /**
828
+ * This method is used internally to resolve a single component from the scope
829
+ *
830
+ * @param component
831
+ * @returns
832
+ */
833
+ private resolveComponent<T extends A_Component>(component: A_TYPES__Component_Constructor<T>): InstanceType<_ComponentType[number]> {
575
834
 
576
835
  // The idea here that in case when Scope has no exact component we have to resolve it from the _parent
577
836
  // BUT: if it's not presented in _parent we have to check for inheritance
578
837
  // That means that we should ensure that there's no components that are children of the required component
579
838
  switch (true) {
580
- // In case when the component is available and exists in the scope
581
- case this.components.includes(component) && this._components.has(component): {
582
- return this._components.get(component);
839
+ // 1) In case when the component is available and exists in the scope
840
+ case this.allowedComponents.has(component) && this._components.has(component): {
841
+ return this._components.get(component)!;
583
842
  }
584
843
 
585
- // In case the component available but does NOT exist in the scope
586
- case this.components.includes(component) && !this._components.has(component): {
844
+ // 2) In case the component available but does NOT exist in the scope
845
+ case this.allowedComponents.has(component) && !this._components.has(component): {
587
846
  const componentMeta = A_Context.meta(component)
588
847
 
589
848
  const argsMeta = componentMeta.get(A_TYPES__ComponentMetaKey.INJECTIONS);
@@ -597,27 +856,27 @@ export class A_Scope {
597
856
  instructions
598
857
  );
599
858
  }
600
- return this.resolve(arg.target)
859
+ // TODO: Fix types mismatch here
860
+ return this.resolve<T>(arg.target as any);
601
861
  });
602
862
 
603
863
  const newComponent = new component(...resolvedArgs)
604
864
 
605
865
  this.register(newComponent);
606
866
 
607
- return this._components.get(component);
867
+ return this._components.get(component)!;
608
868
  }
609
869
 
610
- // In case when there's a component that is inherited from the required component
611
- case !this.components.includes(component) && this.components.some(el => A_CommonHelper.isInheritedFrom(el, component)): {
870
+ // 3) In case when there's a component that is inherited from the required component
871
+ case !this.allowedComponents.has(component) && Array.from(this.allowedComponents).some(el => A_CommonHelper.isInheritedFrom(el, component)): {
872
+ const found = Array.from(this.allowedComponents).find(el => A_CommonHelper.isInheritedFrom(el, component))!;
612
873
 
613
- const found = this.components.find(el => A_CommonHelper.isInheritedFrom(el, component));
614
-
615
- return this.resolveComponent<T>(found as any);
874
+ return this.resolveComponent(found);
616
875
  }
617
876
 
618
- // In case when the component is not available in the scope but the _parent is available
619
- case !this.components.includes(component) && !!this._parent: {
620
- return this._parent.resolveComponent(component);
877
+ // 4) In case when the component is not available in the scope but the _parent is available
878
+ case !!this._parent: {
879
+ return this._parent.resolveComponent(component) as InstanceType<_ComponentType[number]>;
621
880
  }
622
881
 
623
882
  default:
@@ -626,120 +885,148 @@ export class A_Scope {
626
885
  }
627
886
 
628
887
 
629
- /**
630
- * Should be similar to resolveEntity but for commands
631
- *
632
- * @param command
633
- */
634
- private resolveCommand<T extends A_Command>(command: {
635
- new(...args: any[]): T
636
- }): T {
637
- const commands = Array.from(this._commands.values());
638
-
639
- const found = commands.find(e => e instanceof command);
640
-
641
- switch (true) {
642
- case !!found:
643
- return found as T;
644
-
645
- case !found && !!this._parent:
646
- return this._parent.resolveCommand(command);
647
-
648
- default:
649
- throw new Error(`Command ${command.name} not found in the scope ${this.name}`);
650
- }
651
- }
652
-
653
-
654
-
655
888
  /**
656
889
  * This method is used to register the component in the scope
657
890
  *
658
891
  * @param fragment
659
892
  */
660
- register<T extends A_Component>(component: new (...args: any[]) => T): void
661
- register<T extends A_Entity>(entity: new (...args: any[]) => T): void
662
- register<T extends A_Command>(command: new (...args: any[]) => T): void
663
- register(entity: A_Entity): void
664
- register(component: A_Component): void
665
- register(fragment: A_Fragment): void
893
+ register<T extends A_Component>(
894
+ /**
895
+ * Provide a component constructor to register it in the scope
896
+ */
897
+ component: A_TYPES__Component_Constructor<T>
898
+ ): void
899
+ register(
900
+ /**
901
+ * Provide a command instance to register it in the scope
902
+ */
903
+ component: A_Component
904
+ ): void
905
+ register<T extends A_Error>(
906
+ /**
907
+ * Provide an error constructor to register it in the scope
908
+ */
909
+ error: A_TYPES__Error_Constructor<T>
910
+ ): void
911
+ register(
912
+ /**
913
+ * Provide an error instance to register it in the scope
914
+ */
915
+ error: A_Error
916
+ ): void
917
+ register<T extends A_Fragment>(
918
+ /**
919
+ * Provide a command instance to register it in the scope
920
+ */
921
+ fragment: A_TYPES__Fragment_Constructor<T>
922
+ ): void
923
+ register(
924
+ /**
925
+ * Provide a fragment instance to register it in the scope
926
+ */
927
+ fragment: A_Fragment
928
+ ): void
929
+ register<T extends A_Entity>(
930
+ /**
931
+ * Provide an entity constructor to register it in the scope
932
+ */
933
+ entity: A_TYPES__Entity_Constructor<T>
934
+ ): void
935
+ register(
936
+ /**
937
+ * Provide an entity instance to register it in the scope
938
+ */
939
+ entity: A_Entity
940
+ ): void
941
+
666
942
  register(
667
- param1: A_Fragment
668
- | A_Component
669
- | A_Entity
670
- | (new (...args: any[]) => A_Component)
671
- | (new (...args: any[]) => A_Entity)
672
- | (new (...args: any[]) => A_Command)
943
+ param1: unknown
673
944
  ): void {
674
945
  switch (true) {
675
- case param1 instanceof A_Component && !this._components.has(param1.constructor): {
676
- this._components.set(param1.constructor, param1);
946
+ // ------------------------------------------
947
+ // ------------ Instances ----------------
948
+ // ------------------------------------------
949
+ // 1) In case when it's a A-Component instance
950
+ case param1 instanceof A_Component: {
677
951
 
678
- const allowedComponent = this.components.find(c => c === param1.constructor);
952
+ if (!this.allowedComponents.has(param1.constructor as _ComponentType[number]))
953
+ this.allowedComponents.add(param1.constructor as _ComponentType[number]);
679
954
 
680
- if (!allowedComponent) {
681
- this.components.push(param1.constructor as any);
682
- }
955
+ this._components.set(
956
+ param1.constructor as _ComponentType[number],
957
+ param1 as InstanceType<_ComponentType[number]>
958
+ );
683
959
 
684
960
  A_Context.register(this, param1);
685
- break;
686
- }
687
961
 
688
- case param1 instanceof A_Entity && !this._entities.has(param1.aseid.toString()): {
689
- this._entities.set(param1.aseid.toString(), param1);
690
- A_Context.register(this, param1);
691
962
  break;
692
963
  }
964
+ // 3) In case when it's a A-Entity instance
965
+ case param1 instanceof A_Entity && !this._entities.has(param1.aseid.toString()): {
693
966
 
694
- case param1 instanceof A_Fragment && !this._fragments.has(param1.constructor): {
695
- const allowedFragment = this.fragments.find(fr => fr instanceof param1.constructor);
696
-
697
- if (!allowedFragment) {
698
- this.fragments.push(param1);
699
- }
967
+ if (!this.allowedEntities.has(param1.constructor as _EntityType[number]))
968
+ this.allowedEntities.add(param1.constructor as _EntityType[number]);
700
969
 
701
- this._fragments.set(param1.constructor, param1);
970
+ this._entities.set(param1.aseid.toString(), param1 as InstanceType<_EntityType[number]>);
702
971
  A_Context.register(this, param1);
703
972
  break;
704
973
  }
974
+ // 4) In case when it's a A-Fragment instance
975
+ case param1 instanceof A_Fragment: {
705
976
 
706
- case param1 instanceof A_Component: {
707
- this._components.set(param1.constructor, param1);
708
-
709
- const allowedComponent = this.components.find(c => c === param1.constructor);
977
+ if (!this.allowedFragments.has(param1.constructor as A_TYPES__Fragment_Constructor<_FragmentType[number]>))
978
+ this.allowedFragments.add(param1.constructor as A_TYPES__Fragment_Constructor<_FragmentType[number]>);
710
979
 
711
- if (!allowedComponent) {
712
- this.components.push(param1.constructor as any);
713
- }
980
+ this._fragments.set(
981
+ param1.constructor as A_TYPES__Fragment_Constructor<_FragmentType[number]>,
982
+ param1 as _FragmentType[number]
983
+ );
714
984
 
715
985
  A_Context.register(this, param1);
986
+
716
987
  break;
717
988
  }
989
+ // 5) In case when it's a A-Error instance
990
+ case param1 instanceof A_Error: {
991
+ if (!this.allowedErrors.has(param1.constructor as _ErrorType[number]))
992
+ this.allowedErrors.add(param1.constructor as _ErrorType[number]);
718
993
 
719
- case typeof param1 === 'function' && A_CommonHelper.isInheritedFrom(param1, A_Component): {
720
- const allowedComponent = this.components.find(c => c === param1);
721
-
722
- if (!allowedComponent)
723
- this.components.push(param1);
994
+ // A_Context.register(this, param1);
724
995
  break;
725
996
  }
726
- case typeof param1 === 'function' && A_CommonHelper.isInheritedFrom(param1, A_Entity): {
727
- const allowedEntity = this.params.entities.find(e => e.constructor === param1);
728
997
 
729
- if (!allowedEntity) {
730
- this.params.entities.push(new (param1 as any)());
731
- }
998
+ // ------------------------------------------
999
+ // ------------ Constructors ----------------
1000
+ // ------------------------------------------
1001
+ // 6) In case when it's a A-Component constructor
1002
+ case A_TypeGuards.isComponentConstructor(param1): {
1003
+ if (!this.allowedComponents.has(param1))
1004
+ this.allowedComponents.add(param1 as _ComponentType[number]);
732
1005
  break;
733
1006
  }
734
- case typeof param1 === 'function' && A_CommonHelper.isInheritedFrom(param1, A_Command): {
735
- const allowedCommand = this.commands.find(c => c === param1);
736
-
737
- if (!allowedCommand) {
738
- this.commands.push(param1 as any);
739
- }
1007
+ // 8) In case when it's a A-Fragment constructor
1008
+ case A_TypeGuards.isFragmentConstructor(param1): {
1009
+ if (!this.allowedFragments.has(param1))
1010
+ this.allowedFragments.add(param1 as A_TYPES__Fragment_Constructor<_FragmentType[number]>);
1011
+ break;
1012
+ }
1013
+ // 9) In case when it's a A-Entity constructor
1014
+ case A_TypeGuards.isEntityConstructor(param1): {
1015
+ if (!this.allowedEntities.has(param1))
1016
+ this.allowedEntities.add(param1 as _EntityType[number]);
1017
+ break;
1018
+ }
1019
+ // 10) In case when it's a A-Error constructor
1020
+ case A_TypeGuards.isErrorConstructor(param1): {
1021
+ if (!this.allowedErrors.has(param1))
1022
+ this.allowedErrors.add(param1 as _ErrorType[number]);
740
1023
  break;
741
1024
  }
742
1025
 
1026
+ // ------------------------------------------
1027
+ // ------------ Invalid Cases ----------------
1028
+ // ------------------------------------------
1029
+
743
1030
  default:
744
1031
  if (param1 instanceof A_Entity)
745
1032
  throw new Error(`Entity with ASEID ${param1.aseid.toString()} is already registered in the scope ${this.name}`);
@@ -748,23 +1035,134 @@ export class A_Scope {
748
1035
  else
749
1036
  throw new Error(`Cannot register ${param1} in the scope ${this.name}`);
750
1037
  }
1038
+ }
1039
+
751
1040
 
752
1041
 
753
1042
 
1043
+ /**
1044
+ * This method is useful when you want to serialize the scope to JSON
1045
+ *
1046
+ * [!] Note this is not a deep serialization, only the fragments are serialized
1047
+ * [!] Fragments are a storage for information which is relevant to the scope
1048
+ *
1049
+ * @returns
1050
+ */
1051
+ toJSON(): Record<string, any> {
1052
+ return this.fragments
1053
+ .reduce((acc, fragment) => {
1054
+
1055
+ const serialized = fragment.toJSON()
1056
+
1057
+ return {
1058
+ ...acc,
1059
+ [serialized.name]: serialized
1060
+ }
1061
+ }, {});
754
1062
  }
755
1063
 
756
1064
 
757
1065
 
1066
+ //==========================================================================
1067
+ // --------------------Scope Type Check Helpers---------------------------
1068
+ //==========================================================================
1069
+ /**
1070
+ * Type guard to check if the constructor is of type A_Component and is allowed in the scope
1071
+ *
1072
+ * @param ctor
1073
+ * @returns
1074
+ */
1075
+ protected isAllowedComponent(ctor: unknown): ctor is _ComponentType[number] {
1076
+ return A_TypeGuards.isComponentConstructor(ctor) && this.allowedComponents.has(ctor);
1077
+ }
1078
+ /**
1079
+ * Type guard to check if the constructor is of type A_Entity and is allowed in the scope
1080
+ *
1081
+ * @param ctor
1082
+ * @returns
1083
+ */
1084
+ protected isAllowedEntity(ctor: unknown): ctor is A_TYPES__Entity_Constructor<_EntityType[number]> {
1085
+ return A_TypeGuards.isEntityConstructor(ctor) && this.allowedEntities.has(ctor);
1086
+ }
1087
+ /**
1088
+ * Type guard to check if the constructor is of type A_Fragment and is allowed in the scope
1089
+ *
1090
+ * @param ctor
1091
+ * @returns
1092
+ */
1093
+ protected isAllowedFragment(ctor: unknown): ctor is A_TYPES__Fragment_Constructor<_FragmentType[number]> {
1094
+ return A_TypeGuards.isFragmentConstructor(ctor) && this.allowedFragments.has(ctor);
1095
+ }
1096
+ /**
1097
+ * Type guard to check if the constructor is of type A_Error and is allowed in the scope
1098
+ *
1099
+ * @param ctor
1100
+ * @returns
1101
+ */
1102
+ protected isAllowedError(ctor: unknown): ctor is A_TYPES__Error_Constructor<_ErrorType[number]> {
1103
+ return A_TypeGuards.isErrorConstructor(ctor) && this.allowedErrors.has(ctor);
1104
+ }
1105
+
758
1106
 
759
- toJSON(): Record<string, any> {
760
- return this.fragments.reduce((acc, fragment) => {
761
1107
 
762
- const serialized = fragment.toJSON()
763
1108
 
764
- return {
765
- ...acc,
766
- [serialized.name]: serialized
1109
+ // ==========================================================================
1110
+ // --------------------DEBUG & Helpers Methods--------------------------------
1111
+ // ===========================================================================
1112
+ /**
1113
+ * This method is used to check if the scope is inherited from another scope
1114
+ *
1115
+ * @param scope
1116
+ * @returns
1117
+ */
1118
+ isInheritedFrom(scope: A_Scope): boolean {
1119
+ let current: A_Scope | undefined = this;
1120
+
1121
+ while (current) {
1122
+ if (current === scope) {
1123
+ return true;
767
1124
  }
768
- }, {});
1125
+ current = current._parent;
1126
+ }
1127
+
1128
+ return false;
769
1129
  }
770
- }
1130
+
1131
+ /**
1132
+ * Helper method to check circular inheritance
1133
+ * Should return a full sequence of inheritance for logging purposes
1134
+ *
1135
+ * @param scope
1136
+ * @returns
1137
+ */
1138
+ checkCircularInheritance(scope: A_Scope): Array<string> | false {
1139
+ const inheritanceChain: Array<string> = [];
1140
+ let current: A_Scope | undefined = this._parent;
1141
+
1142
+ while (current) {
1143
+ inheritanceChain.push(current.name);
1144
+ if (current === scope) {
1145
+ return inheritanceChain;
1146
+ }
1147
+ current = current._parent;
1148
+ }
1149
+
1150
+ return false;
1151
+ }
1152
+
1153
+ /**
1154
+ * Helper method to print the inheritance chain of the scope
1155
+ */
1156
+ printInheritanceChain(): void {
1157
+ const chain: Array<string> = [];
1158
+ let current: A_Scope | undefined = this;
1159
+
1160
+ while (current) {
1161
+ chain.push(current.name);
1162
+ current = current._parent;
1163
+ }
1164
+
1165
+ console.log(chain.join(' -> '));
1166
+ }
1167
+ }
1168
+