@vived/core 1.5.1 → 2.0.0

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 (166) hide show
  1. package/README.md +1 -48
  2. package/dist/cjs/AppObject/AppObjectComponent.js +8 -10
  3. package/dist/cjs/AppObject/AppObjectComponent.js.map +1 -1
  4. package/dist/cjs/AppObject/AppObjectEntityRepo.js +99 -11
  5. package/dist/cjs/AppObject/AppObjectEntityRepo.js.map +1 -1
  6. package/dist/cjs/AppObject/AppObjectPM.js +106 -6
  7. package/dist/cjs/AppObject/AppObjectPM.js.map +1 -1
  8. package/dist/cjs/AppObject/AppObjectRepo.js +11 -1
  9. package/dist/cjs/AppObject/AppObjectRepo.js.map +1 -1
  10. package/dist/cjs/AppObject/AppObjectSingletonEntity.js +40 -0
  11. package/dist/cjs/AppObject/AppObjectSingletonEntity.js.map +1 -0
  12. package/dist/cjs/AppObject/AppObjectSingletonEntityRepo.js +54 -0
  13. package/dist/cjs/AppObject/AppObjectSingletonEntityRepo.js.map +1 -0
  14. package/dist/cjs/AppObject/AppObjectSingletonPM.js +69 -0
  15. package/dist/cjs/AppObject/AppObjectSingletonPM.js.map +1 -0
  16. package/dist/cjs/AppObject/AppObjectSingletonUC.js +60 -0
  17. package/dist/cjs/AppObject/AppObjectSingletonUC.js.map +1 -0
  18. package/dist/cjs/AppObject/index.js +4 -0
  19. package/dist/cjs/AppObject/index.js.map +1 -1
  20. package/dist/cjs/DomainFactories/Entities/DomainFactoryRepo.js +5 -0
  21. package/dist/cjs/DomainFactories/Entities/DomainFactoryRepo.js.map +1 -1
  22. package/dist/cjs/Entities/ObserverList.js +6 -0
  23. package/dist/cjs/Entities/ObserverList.js.map +1 -1
  24. package/dist/cjs/ExampleFeature/Entities/ExampleRepo.js +11 -22
  25. package/dist/cjs/ExampleFeature/Entities/ExampleRepo.js.map +1 -1
  26. package/dist/cjs/ExampleFeature/Entities/ExampleSingletonEntity.js +1 -3
  27. package/dist/cjs/ExampleFeature/Entities/ExampleSingletonEntity.js.map +1 -1
  28. package/dist/cjs/ExampleFeature/Factory/ExampleFeatureFactory.js +65 -0
  29. package/dist/cjs/ExampleFeature/Factory/ExampleFeatureFactory.js.map +1 -0
  30. package/dist/cjs/ExampleFeature/PMs/ExamplePM.js +5 -13
  31. package/dist/cjs/ExampleFeature/PMs/ExamplePM.js.map +1 -1
  32. package/dist/cjs/ExampleFeature/PMs/ExampleSingletonPM.js +8 -12
  33. package/dist/cjs/ExampleFeature/PMs/ExampleSingletonPM.js.map +1 -1
  34. package/dist/cjs/ExampleFeature/UCs/EditExampleStringUC.js +0 -4
  35. package/dist/cjs/ExampleFeature/UCs/EditExampleStringUC.js.map +1 -1
  36. package/dist/cjs/ExampleFeature/UCs/ToggleExampleBooleanUC.js +2 -8
  37. package/dist/cjs/ExampleFeature/UCs/ToggleExampleBooleanUC.js.map +1 -1
  38. package/dist/cjs/index.js +0 -1
  39. package/dist/cjs/index.js.map +1 -1
  40. package/dist/esm/AppObject/AppObjectComponent.js +8 -10
  41. package/dist/esm/AppObject/AppObjectComponent.js.map +1 -1
  42. package/dist/esm/AppObject/AppObjectEntityRepo.js +99 -11
  43. package/dist/esm/AppObject/AppObjectEntityRepo.js.map +1 -1
  44. package/dist/esm/AppObject/AppObjectPM.js +107 -7
  45. package/dist/esm/AppObject/AppObjectPM.js.map +1 -1
  46. package/dist/esm/AppObject/AppObjectRepo.js +11 -1
  47. package/dist/esm/AppObject/AppObjectRepo.js.map +1 -1
  48. package/dist/esm/AppObject/AppObjectSingletonEntity.js +36 -0
  49. package/dist/esm/AppObject/AppObjectSingletonEntity.js.map +1 -0
  50. package/dist/esm/AppObject/AppObjectSingletonEntityRepo.js +50 -0
  51. package/dist/esm/AppObject/AppObjectSingletonEntityRepo.js.map +1 -0
  52. package/dist/esm/AppObject/AppObjectSingletonPM.js +65 -0
  53. package/dist/esm/AppObject/AppObjectSingletonPM.js.map +1 -0
  54. package/dist/esm/AppObject/AppObjectSingletonUC.js +56 -0
  55. package/dist/esm/AppObject/AppObjectSingletonUC.js.map +1 -0
  56. package/dist/esm/AppObject/index.js +4 -0
  57. package/dist/esm/AppObject/index.js.map +1 -1
  58. package/dist/esm/DomainFactories/Entities/DomainFactoryRepo.js +4 -0
  59. package/dist/esm/DomainFactories/Entities/DomainFactoryRepo.js.map +1 -1
  60. package/dist/esm/Entities/ObserverList.js +6 -0
  61. package/dist/esm/Entities/ObserverList.js.map +1 -1
  62. package/dist/esm/ExampleFeature/Entities/ExampleRepo.js +11 -22
  63. package/dist/esm/ExampleFeature/Entities/ExampleRepo.js.map +1 -1
  64. package/dist/esm/ExampleFeature/Entities/ExampleSingletonEntity.js +2 -4
  65. package/dist/esm/ExampleFeature/Entities/ExampleSingletonEntity.js.map +1 -1
  66. package/dist/esm/ExampleFeature/Factory/ExampleFeatureFactory.js +60 -0
  67. package/dist/esm/ExampleFeature/Factory/ExampleFeatureFactory.js.map +1 -0
  68. package/dist/esm/ExampleFeature/PMs/ExamplePM.js +5 -13
  69. package/dist/esm/ExampleFeature/PMs/ExamplePM.js.map +1 -1
  70. package/dist/esm/ExampleFeature/PMs/ExampleSingletonPM.js +9 -13
  71. package/dist/esm/ExampleFeature/PMs/ExampleSingletonPM.js.map +1 -1
  72. package/dist/esm/ExampleFeature/UCs/EditExampleStringUC.js +0 -4
  73. package/dist/esm/ExampleFeature/UCs/EditExampleStringUC.js.map +1 -1
  74. package/dist/esm/ExampleFeature/UCs/ToggleExampleBooleanUC.js +3 -9
  75. package/dist/esm/ExampleFeature/UCs/ToggleExampleBooleanUC.js.map +1 -1
  76. package/dist/esm/index.js +0 -1
  77. package/dist/esm/index.js.map +1 -1
  78. package/dist/types/AppObject/AppObjectComponent.d.ts +6 -4
  79. package/dist/types/AppObject/AppObjectComponent.d.ts.map +1 -1
  80. package/dist/types/AppObject/AppObjectEntityRepo.d.ts +72 -7
  81. package/dist/types/AppObject/AppObjectEntityRepo.d.ts.map +1 -1
  82. package/dist/types/AppObject/AppObjectPM.d.ts +82 -2
  83. package/dist/types/AppObject/AppObjectPM.d.ts.map +1 -1
  84. package/dist/types/AppObject/AppObjectRepo.d.ts +13 -0
  85. package/dist/types/AppObject/AppObjectRepo.d.ts.map +1 -1
  86. package/dist/types/AppObject/AppObjectSingletonEntity.d.ts +31 -0
  87. package/dist/types/AppObject/AppObjectSingletonEntity.d.ts.map +1 -0
  88. package/dist/types/AppObject/AppObjectSingletonEntityRepo.d.ts +46 -0
  89. package/dist/types/AppObject/AppObjectSingletonEntityRepo.d.ts.map +1 -0
  90. package/dist/types/AppObject/AppObjectSingletonPM.d.ts +60 -0
  91. package/dist/types/AppObject/AppObjectSingletonPM.d.ts.map +1 -0
  92. package/dist/types/AppObject/AppObjectSingletonUC.d.ts +51 -0
  93. package/dist/types/AppObject/AppObjectSingletonUC.d.ts.map +1 -0
  94. package/dist/types/AppObject/index.d.ts +4 -0
  95. package/dist/types/AppObject/index.d.ts.map +1 -1
  96. package/dist/types/DomainFactories/Entities/DomainFactoryRepo.d.ts +1 -0
  97. package/dist/types/DomainFactories/Entities/DomainFactoryRepo.d.ts.map +1 -1
  98. package/dist/types/Entities/ObserverList.d.ts +4 -0
  99. package/dist/types/Entities/ObserverList.d.ts.map +1 -1
  100. package/dist/types/ExampleFeature/Entities/ExampleRepo.d.ts +0 -4
  101. package/dist/types/ExampleFeature/Entities/ExampleRepo.d.ts.map +1 -1
  102. package/dist/types/ExampleFeature/Entities/ExampleSingletonEntity.d.ts +2 -2
  103. package/dist/types/ExampleFeature/Entities/ExampleSingletonEntity.d.ts.map +1 -1
  104. package/dist/types/ExampleFeature/Factory/ExampleFeatureFactory.d.ts +44 -0
  105. package/dist/types/ExampleFeature/Factory/ExampleFeatureFactory.d.ts.map +1 -0
  106. package/dist/types/ExampleFeature/PMs/ExampleSingletonPM.d.ts +4 -4
  107. package/dist/types/ExampleFeature/PMs/ExampleSingletonPM.d.ts.map +1 -1
  108. package/dist/types/ExampleFeature/UCs/ToggleExampleBooleanUC.d.ts +2 -2
  109. package/dist/types/ExampleFeature/UCs/ToggleExampleBooleanUC.d.ts.map +1 -1
  110. package/dist/types/index.d.ts +0 -1
  111. package/dist/types/index.d.ts.map +1 -1
  112. package/package.json +2 -2
  113. package/dist/cjs/ExampleFeature/Adapters/index.js +0 -19
  114. package/dist/cjs/ExampleFeature/Adapters/index.js.map +0 -1
  115. package/dist/cjs/ExampleFeature/Controllers/index.js +0 -19
  116. package/dist/cjs/ExampleFeature/Controllers/index.js.map +0 -1
  117. package/dist/cjs/ExampleFeature/Entities/index.js +0 -20
  118. package/dist/cjs/ExampleFeature/Entities/index.js.map +0 -1
  119. package/dist/cjs/ExampleFeature/Factory/index.js +0 -18
  120. package/dist/cjs/ExampleFeature/Factory/index.js.map +0 -1
  121. package/dist/cjs/ExampleFeature/Factory/setupExampleFeature.js +0 -29
  122. package/dist/cjs/ExampleFeature/Factory/setupExampleFeature.js.map +0 -1
  123. package/dist/cjs/ExampleFeature/Mocks/index.js +0 -21
  124. package/dist/cjs/ExampleFeature/Mocks/index.js.map +0 -1
  125. package/dist/cjs/ExampleFeature/PMs/index.js +0 -19
  126. package/dist/cjs/ExampleFeature/PMs/index.js.map +0 -1
  127. package/dist/cjs/ExampleFeature/UCs/index.js +0 -19
  128. package/dist/cjs/ExampleFeature/UCs/index.js.map +0 -1
  129. package/dist/cjs/ExampleFeature/index.js +0 -24
  130. package/dist/cjs/ExampleFeature/index.js.map +0 -1
  131. package/dist/esm/ExampleFeature/Adapters/index.js +0 -3
  132. package/dist/esm/ExampleFeature/Adapters/index.js.map +0 -1
  133. package/dist/esm/ExampleFeature/Controllers/index.js +0 -3
  134. package/dist/esm/ExampleFeature/Controllers/index.js.map +0 -1
  135. package/dist/esm/ExampleFeature/Entities/index.js +0 -4
  136. package/dist/esm/ExampleFeature/Entities/index.js.map +0 -1
  137. package/dist/esm/ExampleFeature/Factory/index.js +0 -2
  138. package/dist/esm/ExampleFeature/Factory/index.js.map +0 -1
  139. package/dist/esm/ExampleFeature/Factory/setupExampleFeature.js +0 -26
  140. package/dist/esm/ExampleFeature/Factory/setupExampleFeature.js.map +0 -1
  141. package/dist/esm/ExampleFeature/Mocks/index.js +0 -5
  142. package/dist/esm/ExampleFeature/Mocks/index.js.map +0 -1
  143. package/dist/esm/ExampleFeature/PMs/index.js +0 -3
  144. package/dist/esm/ExampleFeature/PMs/index.js.map +0 -1
  145. package/dist/esm/ExampleFeature/UCs/index.js +0 -3
  146. package/dist/esm/ExampleFeature/UCs/index.js.map +0 -1
  147. package/dist/esm/ExampleFeature/index.js +0 -8
  148. package/dist/esm/ExampleFeature/index.js.map +0 -1
  149. package/dist/types/ExampleFeature/Adapters/index.d.ts +0 -3
  150. package/dist/types/ExampleFeature/Adapters/index.d.ts.map +0 -1
  151. package/dist/types/ExampleFeature/Controllers/index.d.ts +0 -3
  152. package/dist/types/ExampleFeature/Controllers/index.d.ts.map +0 -1
  153. package/dist/types/ExampleFeature/Entities/index.d.ts +0 -4
  154. package/dist/types/ExampleFeature/Entities/index.d.ts.map +0 -1
  155. package/dist/types/ExampleFeature/Factory/index.d.ts +0 -2
  156. package/dist/types/ExampleFeature/Factory/index.d.ts.map +0 -1
  157. package/dist/types/ExampleFeature/Factory/setupExampleFeature.d.ts +0 -17
  158. package/dist/types/ExampleFeature/Factory/setupExampleFeature.d.ts.map +0 -1
  159. package/dist/types/ExampleFeature/Mocks/index.d.ts +0 -5
  160. package/dist/types/ExampleFeature/Mocks/index.d.ts.map +0 -1
  161. package/dist/types/ExampleFeature/PMs/index.d.ts +0 -3
  162. package/dist/types/ExampleFeature/PMs/index.d.ts.map +0 -1
  163. package/dist/types/ExampleFeature/UCs/index.d.ts +0 -3
  164. package/dist/types/ExampleFeature/UCs/index.d.ts.map +0 -1
  165. package/dist/types/ExampleFeature/index.d.ts +0 -8
  166. package/dist/types/ExampleFeature/index.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AppObjectEntityRepo.js","sourceRoot":"","sources":["../../../src/AppObject/AppObjectEntityRepo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,mBAEX,SAAQ,eAAe;IAFzB;;QAGU,iBAAY,GAAG,IAAI,GAAG,EAAa,CAAC;QAEpC,2BAAsB,GAAG,IAAI,YAAY,EAAK,CAAC;QACvD;;;;WAIG;QACH,2BAAsB,GAAG,CAAC,QAAkC,EAAE,EAAE;YAC9D,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5C,CAAC,CAAC;QAEF;;;;WAIG;QACH,8BAAyB,GAAG,CAAC,QAAkC,EAAQ,EAAE;YACvE,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/C,CAAC,CAAC;QAEM,6BAAwB,GAAG,IAAI,YAAY,EAAK,CAAC;QACzD;;;;WAIG;QACH,6BAAwB,GAAG,CAAC,QAAoC,EAAE,EAAE;YAClE,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9C,CAAC,CAAC;QAEF;;;;WAIG;QACH,gCAA2B,GAAG,CAC5B,QAAoC,EAC9B,EAAE;YACR,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjD,CAAC,CAAC;QAEF;;;;;WAKG;QACH,oBAAe,GAAG,CAAC,WAAmB,EAAW,EAAE;YACjD,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC5C,CAAC,CAAC;QAsBF;;;;;;WAMG;QACH,uBAAkB,GAAG,CAAC,EAAU,EAAE,EAAE;YAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC3C,IAAI,CAAC,QAAQ;gBAAE,OAAO;YAEtB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC7B,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACnD,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjD,CAAC,CAAC;QAEF;;;;;WAKG;QACH,oBAAe,GAAG,CAAC,WAAmB,EAAiB,EAAE;YACvD,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC5C,CAAC,CAAC;QAEF;;;;WAIG;QACH,WAAM,GAAG,GAAQ,EAAE;YACjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;QAChD,CAAC,CAAC;IACJ,CAAC;IAvDC;;;;;;;OAOG;IACH,GAAG,CAAC,MAAS;QACX,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC5D,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACnD,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC9C,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;CAqCF","sourcesContent":["import { ObserverList } from \"../Entities\";\r\nimport { AppObjectEntity } from \"./AppObjectEntity\";\r\n\r\n/**\r\n * A repository for managing collections of AppObjectEntity instances.\r\n *\r\n * This generic class provides a centralized way to store, retrieve, and manage\r\n * entities that are associated with specific AppObjects. It implements the observer\r\n * pattern to notify listeners when entities are added or removed.\r\n *\r\n * @template T - The type of entities managed by this repository, must extend AppObjectEntity\r\n * @extends AppObjectEntity\r\n *\r\n * @example\r\n * ```typescript\r\n * // Create a repository for player entities\r\n * const playerRepo = new AppObjectEntityRepo<PlayerEntity>();\r\n *\r\n * // Add a new player\r\n * const player = new PlayerEntity(appObject);\r\n * playerRepo.add(player);\r\n *\r\n * // Get a player by its AppObject ID\r\n * const retrievedPlayer = playerRepo.getForAppObject(\"player1\");\r\n * ```\r\n */\r\nexport class AppObjectEntityRepo<\r\n T extends AppObjectEntity,\r\n> extends AppObjectEntity {\r\n private entityLookup = new Map<string, T>();\r\n\r\n private onEntityAddedObservers = new ObserverList<T>();\r\n /**\r\n * Registers an observer to be notified when an entity is added to the repository.\r\n *\r\n * @param {(addedEntity: T) => void} observer - The callback function to invoke when an entity is added\r\n */\r\n addEntityAddedObserver = (observer: (addedEntity: T) => void) => {\r\n this.onEntityAddedObservers.add(observer);\r\n };\r\n\r\n /**\r\n * Removes an observer previously registered for entity addition notifications.\r\n *\r\n * @param {(addedEntity: T) => void} observer - The callback function to remove\r\n */\r\n removeEntityAddedObserver = (observer: (addedEntity: T) => void): void => {\r\n this.onEntityAddedObservers.remove(observer);\r\n };\r\n\r\n private onEntityRemovedObservers = new ObserverList<T>();\r\n /**\r\n * Registers an observer to be notified when an entity is removed from the repository.\r\n *\r\n * @param {(removedEntity: T) => void} observer - The callback function to invoke when an entity is removed\r\n */\r\n addEntityRemovedObserver = (observer: (removedEntity: T) => void) => {\r\n this.onEntityRemovedObservers.add(observer);\r\n };\r\n\r\n /**\r\n * Removes an observer previously registered for entity removal notifications.\r\n *\r\n * @param {(removedEntity: T) => void} observer - The callback function to remove\r\n */\r\n removeEntityRemovedObserver = (\r\n observer: (removedEntity: T) => void\r\n ): void => {\r\n this.onEntityRemovedObservers.remove(observer);\r\n };\r\n\r\n /**\r\n * Checks if an entity exists for the given AppObject ID.\r\n *\r\n * @param {string} appObjectID - The ID of the AppObject\r\n * @returns {boolean} True if an entity exists for the given AppObject ID, false otherwise\r\n */\r\n hasForAppObject = (appObjectID: string): boolean => {\r\n return this.entityLookup.has(appObjectID);\r\n };\r\n\r\n /**\r\n * Adds an entity to the repository.\r\n *\r\n * If an entity with the same AppObject ID already exists, it is replaced.\r\n * Notifies all registered observers after the entity is added.\r\n *\r\n * @param {T} entity - The entity to add\r\n */\r\n add(entity: T) {\r\n const existing = this.entityLookup.get(entity.appObject.id);\r\n if (existing) {\r\n existing.removeChangeObserver(this.notifyOnChange);\r\n }\r\n\r\n this.entityLookup.set(entity.appObject.id, entity);\r\n entity.addChangeObserver(this.notifyOnChange);\r\n this.notifyOnChange();\r\n this.onEntityAddedObservers.notify(entity);\r\n }\r\n\r\n /**\r\n * Removes the entity associated with the specified AppObject ID.\r\n *\r\n * Notifies all registered observers after the entity is removed.\r\n *\r\n * @param {string} id - The ID of the AppObject whose entity should be removed\r\n */\r\n removeForAppObject = (id: string) => {\r\n const existing = this.entityLookup.get(id);\r\n if (!existing) return;\r\n\r\n this.entityLookup.delete(id);\r\n existing.removeChangeObserver(this.notifyOnChange);\r\n this.notifyOnChange();\r\n this.onEntityRemovedObservers.notify(existing);\r\n };\r\n\r\n /**\r\n * Gets the entity associated with the specified AppObject ID.\r\n *\r\n * @param {string} appObjectID - The ID of the AppObject\r\n * @returns {T | undefined} The entity if found, undefined otherwise\r\n */\r\n getForAppObject = (appObjectID: string): T | undefined => {\r\n return this.entityLookup.get(appObjectID);\r\n };\r\n\r\n /**\r\n * Gets all entities in the repository.\r\n *\r\n * @returns {T[]} An array of all entities\r\n */\r\n getAll = (): T[] => {\r\n return Array.from(this.entityLookup.values());\r\n };\r\n}\r\n"]}
1
+ {"version":3,"file":"AppObjectEntityRepo.js","sourceRoot":"","sources":["../../../src/AppObject/AppObjectEntityRepo.ts"],"names":[],"mappings":"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","sourcesContent":["import { ObserverList } from \"../Entities\";\r\nimport { generateUniqueID } from \"../Utilities\";\r\nimport { AppObjectEntity } from \"./AppObjectEntity\";\r\n\r\n/**\r\n * A repository for managing collections of AppObjectEntity instances.\r\n *\r\n * This generic class provides a centralized way to store, retrieve, and manage\r\n * entities that are associated with specific AppObjects. It implements the observer\r\n * pattern to notify listeners when entities are added or removed.\r\n *\r\n * Derived classes should override the `entityFactory` method to provide custom\r\n * entity creation logic for the `create` method.\r\n *\r\n * @template T - The type of entities managed by this repository, must extend AppObjectEntity\r\n * @extends AppObjectEntity\r\n *\r\n * @example\r\n * ```typescript\r\n * // Create a custom repository with entity factory\r\n * class PlayerRepo extends AppObjectEntityRepo<PlayerEntity> {\r\n * entityFactory(id: string): PlayerEntity {\r\n * const appObject = makeAppObject(id, this.appObjects);\r\n * return new PlayerEntity(appObject);\r\n * }\r\n * }\r\n *\r\n * const playerRepo = new PlayerRepo(repoAppObject);\r\n *\r\n * // Create a new player with auto-generated ID\r\n * const player = playerRepo.create();\r\n *\r\n * // Create a new player with specific ID\r\n * const specificPlayer = playerRepo.create(\"player1\");\r\n *\r\n * // Get a player by its ID\r\n * const retrievedPlayer = playerRepo.getById(\"player1\");\r\n * ```\r\n */\r\nexport class AppObjectEntityRepo<\r\n T extends AppObjectEntity,\r\n> extends AppObjectEntity {\r\n private entityLookup = new Map<string, T>();\r\n\r\n private onEntityAddedObservers = new ObserverList<T>();\r\n /**\r\n * Registers an observer to be notified when an entity is added to the repository.\r\n *\r\n * @param {(addedEntity: T) => void} observer - The callback function to invoke when an entity is added\r\n */\r\n addEntityAddedObserver = (observer: (addedEntity: T) => void) => {\r\n this.onEntityAddedObservers.add(observer);\r\n };\r\n\r\n /**\r\n * Removes an observer previously registered for entity addition notifications.\r\n *\r\n * @param {(addedEntity: T) => void} observer - The callback function to remove\r\n */\r\n removeEntityAddedObserver = (observer: (addedEntity: T) => void): void => {\r\n this.onEntityAddedObservers.remove(observer);\r\n };\r\n\r\n private onEntityRemovedObservers = new ObserverList<T>();\r\n /**\r\n * Registers an observer to be notified when an entity is removed from the repository.\r\n *\r\n * @param {(removedEntity: T) => void} observer - The callback function to invoke when an entity is removed\r\n */\r\n addEntityRemovedObserver = (observer: (removedEntity: T) => void) => {\r\n this.onEntityRemovedObservers.add(observer);\r\n };\r\n\r\n /**\r\n * Removes an observer previously registered for entity removal notifications.\r\n *\r\n * @param {(removedEntity: T) => void} observer - The callback function to remove\r\n */\r\n removeEntityRemovedObserver = (\r\n observer: (removedEntity: T) => void\r\n ): void => {\r\n this.onEntityRemovedObservers.remove(observer);\r\n };\r\n\r\n /**\r\n * Checks if an entity exists for the given ID.\r\n *\r\n * @param {string} id - The ID of the AppObject\r\n * @returns {boolean} True if an entity exists for the given ID, false otherwise\r\n */\r\n has = (id: string): boolean => {\r\n return this.entityLookup.has(id);\r\n };\r\n\r\n /**\r\n * Checks if an entity exists for the given AppObject ID.\r\n *\r\n * @param {string} appObjectID - The ID of the AppObject\r\n * @returns {boolean} True if an entity exists for the given AppObject ID, false otherwise\r\n * @deprecated Use has instead\r\n */\r\n hasForAppObject = (appObjectID: string): boolean => {\r\n return this.has(appObjectID);\r\n };\r\n\r\n /**\r\n * Adds an entity to the repository.\r\n *\r\n * If an entity with the same AppObject ID already exists, it is replaced.\r\n * Notifies all registered observers after the entity is added.\r\n *\r\n * @param {T} entity - The entity to add\r\n */\r\n add(entity: T) {\r\n const existing = this.entityLookup.get(entity.appObject.id);\r\n if (existing) {\r\n existing.removeChangeObserver(this.notifyOnChange);\r\n }\r\n\r\n this.entityLookup.set(entity.appObject.id, entity);\r\n entity.addChangeObserver(this.notifyOnChange);\r\n this.notifyOnChange();\r\n this.onEntityAddedObservers.notify(entity);\r\n }\r\n\r\n /**\r\n * Creates a new entity with the specified or auto-generated ID and adds it to the repository.\r\n *\r\n * This method uses the `entityFactory` method to create the entity instance.\r\n * If no ID is provided, a unique ID is generated automatically.\r\n *\r\n * @param {string} [id] - Optional ID for the entity. If not provided, a unique ID is generated.\r\n * @returns {T} The newly created entity\r\n */\r\n create(id?: string): T {\r\n const idToUse = id ?? generateUniqueID();\r\n const entity = this.entityFactory(idToUse);\r\n this.add(entity);\r\n return entity;\r\n }\r\n\r\n /**\r\n * Factory method for creating entity instances.\r\n *\r\n * This method must be overridden in derived classes to provide custom entity creation logic.\r\n * It is called by the `create` method to instantiate new entities.\r\n *\r\n * @param {string} id - The ID to use for the new entity\r\n * @returns {T} A new entity instance\r\n * @throws {Error} If not overridden in derived class\r\n */\r\n entityFactory(id: string): T {\r\n // Override this method in derived classes to provide entity creation logic\r\n throw new Error(\"Entity factory not implemented.\");\r\n }\r\n\r\n /**\r\n * Removes the entity associated with the specified ID.\r\n *\r\n * Notifies all registered observers after the entity is removed.\r\n *\r\n * @param {string} id - The ID of the AppObject whose entity should be removed\r\n */\r\n removeById = (id: string) => {\r\n const existing = this.entityLookup.get(id);\r\n if (!existing) return;\r\n\r\n this.entityLookup.delete(id);\r\n existing.removeChangeObserver(this.notifyOnChange);\r\n this.notifyOnChange();\r\n this.onEntityRemovedObservers.notify(existing);\r\n };\r\n\r\n /**\r\n * Removes the entity associated with the specified AppObject ID.\r\n *\r\n * Notifies all registered observers after the entity is removed.\r\n *\r\n * @param {string} id - The ID of the AppObject whose entity should be removed\r\n * @deprecated Use removeById instead\r\n */\r\n removeForAppObject = (id: string) => {\r\n this.removeById(id);\r\n };\r\n\r\n /**\r\n * Removes all entities from the repository.\r\n *\r\n * Unsubscribes from all entity change observers and notifies all registered\r\n * removal observers for each entity before clearing the repository.\r\n */\r\n deleteAll = () => {\r\n const entities = Array.from(this.entityLookup.values());\r\n\r\n entities.forEach((entity) => {\r\n entity.removeChangeObserver(this.notifyOnChange);\r\n this.onEntityRemovedObservers.notify(entity);\r\n });\r\n\r\n this.entityLookup.clear();\r\n this.notifyOnChange();\r\n };\r\n\r\n /**\r\n * Gets the entity associated with the specified ID.\r\n *\r\n * @param {string} id - The ID of the AppObject\r\n * @returns {T | undefined} The entity if found, undefined otherwise\r\n */\r\n getById = (id: string): T | undefined => {\r\n return this.entityLookup.get(id);\r\n };\r\n\r\n /**\r\n * Gets the entity associated with the specified AppObject ID.\r\n *\r\n * @param {string} appObjectID - The ID of the AppObject\r\n * @returns {T | undefined} The entity if found, undefined otherwise\r\n * @deprecated Use getById instead\r\n */\r\n getForAppObject = (appObjectID: string): T | undefined => {\r\n return this.getById(appObjectID);\r\n };\r\n\r\n /**\r\n * Gets all entities in the repository.\r\n *\r\n * @returns {T[]} An array of all entities\r\n */\r\n getAll = (): T[] => {\r\n return Array.from(this.entityLookup.values());\r\n };\r\n}\r\n"]}
@@ -1,5 +1,5 @@
1
1
  import { ObserverList } from "../Entities";
2
- import { AppObjectComponent, AppObjectComponentType } from "./AppObjectComponent";
2
+ import { AppObjectComponent, AppObjectComponentType, } from "./AppObjectComponent";
3
3
  /**
4
4
  * Presentation Manager (PM) component that transforms application state into view models
5
5
  *
@@ -21,13 +21,21 @@ export class AppObjectPM extends AppObjectComponent {
21
21
  /** Identifies this as a Presentation Manager component */
22
22
  this.componentType = AppObjectComponentType.PM;
23
23
  /** List of view update functions to notify when the view model changes */
24
- this.observerList = new ObserverList();
24
+ this.views = new ObserverList();
25
+ /**
26
+ * List of entities being observed by this PM.
27
+ * Used for automatic cleanup during disposal.
28
+ */
29
+ this.observedEntities = [];
25
30
  }
26
31
  /**
27
32
  * Gets the most recently generated view model
28
- * @returns The last view model or undefined if none has been generated
33
+ * @returns The last view model, or `defaultVM` if no view model has been generated yet,
34
+ * or undefined if neither exists
29
35
  */
30
36
  get lastVM() {
37
+ if (!this._lastVM)
38
+ return this.defaultVM;
31
39
  return this._lastVM;
32
40
  }
33
41
  /**
@@ -37,11 +45,92 @@ export class AppObjectPM extends AppObjectComponent {
37
45
  * @param updateView Function to call with updated view models
38
46
  */
39
47
  addView(updateView) {
40
- this.observerList.add(updateView);
48
+ if (this.views.length === 0) {
49
+ // There are no views yet - generate the initial view model
50
+ this.formVM();
51
+ }
52
+ this.views.add(updateView);
41
53
  // Immediately update the view with current view model if one exists
42
54
  if (this._lastVM !== undefined) {
43
55
  updateView(this._lastVM);
44
56
  }
57
+ this.onViewAdded();
58
+ }
59
+ /**
60
+ * Called when an observed entity changes.
61
+ * If views are registered, this method calls `formVM()` to regenerate the view model.
62
+ *
63
+ * This method is automatically invoked when entities registered via `observeEntity()`
64
+ * notify their observers. It implements lazy evaluation - view models are only
65
+ * formed when there are views to receive them.
66
+ */
67
+ onEntityChanged() {
68
+ if (this.views.length === 0) {
69
+ return;
70
+ }
71
+ else {
72
+ this.formVM();
73
+ }
74
+ }
75
+ /**
76
+ * Forms and updates the view model based on current entity state.
77
+ *
78
+ * Override this method in derived classes to:
79
+ * 1. Read data from observed entities
80
+ * 2. Transform the data into a view model
81
+ * 3. Call `doUpdateView(vm)` with the new view model
82
+ *
83
+ * This method is only called when at least one view has been registered,
84
+ * implementing lazy evaluation to avoid unnecessary computation.
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * formVM(): void {
89
+ * const entity = this.getCachedLocalComponent<MyEntity>(MyEntity.type);
90
+ * if (entity) {
91
+ * this.doUpdateView({
92
+ * displayName: entity.name,
93
+ * isActive: entity.active
94
+ * });
95
+ * }
96
+ * }
97
+ * ```
98
+ */
99
+ formVM() {
100
+ // To be implemented by derived classes
101
+ // Form up the VM and then call doUpdateView(vm: T)
102
+ // This will only be called if at least one view has been registered
103
+ }
104
+ onViewAdded() {
105
+ // Can be overridden by derived classes to react when the first view is added
106
+ }
107
+ /**
108
+ * Registers an entity to be observed for changes.
109
+ *
110
+ * When the entity notifies of changes (via `notifyOnChange()`), this PM will
111
+ * automatically call `onEntityChanged()`, which in turn calls `formVM()` if
112
+ * views are registered.
113
+ *
114
+ * The entity observer is automatically cleaned up when this PM is disposed.
115
+ *
116
+ * @param entity The entity to observe for changes
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * constructor(appObj: AppObject) {
121
+ * super(appObj, MyPM.type);
122
+ * const entity = appObj.getComponent<MyEntity>(MyEntity.type);
123
+ * if (entity) {
124
+ * this.observeEntity(entity);
125
+ * }
126
+ * }
127
+ * ```
128
+ */
129
+ observeEntity(entity) {
130
+ entity.addChangeObserver(() => {
131
+ this.onEntityChanged();
132
+ });
133
+ this.observedEntities.push(entity);
45
134
  }
46
135
  /**
47
136
  * Unregisters a previously added view update function
@@ -49,7 +138,7 @@ export class AppObjectPM extends AppObjectComponent {
49
138
  * @param updateView The view update function to remove
50
139
  */
51
140
  removeView(updateView) {
52
- this.observerList.remove(updateView);
141
+ this.views.remove(updateView);
53
142
  }
54
143
  /**
55
144
  * Updates the view model and notifies all registered views if the model has changed
@@ -66,13 +155,24 @@ export class AppObjectPM extends AppObjectComponent {
66
155
  return;
67
156
  }
68
157
  this._lastVM = vm;
69
- this.observerList.notify(vm);
158
+ this.views.notify(vm);
70
159
  }
71
160
  /**
72
161
  * Cleans up resources and detaches this PM from its parent AppObject
162
+ *
163
+ * This method:
164
+ * 1. Removes change observers from all observed entities
165
+ * 2. Clears all view observers
166
+ * 3. Removes this component from its parent AppObject if still attached
167
+ * 4. Calls the parent class dispose method
73
168
  */
74
169
  dispose() {
75
- this.observerList.clear();
170
+ this.observedEntities.forEach((entity) => {
171
+ entity.removeChangeObserver(() => {
172
+ this.onEntityChanged();
173
+ });
174
+ });
175
+ this.views.clear();
76
176
  if (this.appObject.getComponent(this.type) === this) {
77
177
  this.appObject.removeComponent(this.type);
78
178
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AppObjectPM.js","sourceRoot":"","sources":["../../../src/AppObject/AppObjectPM.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAElF;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAgB,WAAe,SAAQ,kBAAkB;IAA/D;;QACE,0DAA0D;QACjD,kBAAa,GAAG,sBAAsB,CAAC,EAAE,CAAC;QAuBnD,0EAA0E;QAClE,iBAAY,GAAG,IAAI,YAAY,EAAK,CAAC;IAuD/C,CAAC;IAhEC;;;OAGG;IACH,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAKD;;;;;OAKG;IACH,OAAO,CAAC,UAA2B;QACjC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAElC,oEAAoE;QACpE,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/B,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,UAA2B;QACpC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAED;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAK;QAChB,+CAA+C;QAC/C,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;YACvD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACpD,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC;QACD,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;CACF","sourcesContent":["import { ObserverList } from \"../Entities\";\r\nimport { AppObjectComponent, AppObjectComponentType } from \"./AppObjectComponent\";\r\n\r\n/**\r\n * Presentation Manager (PM) component that transforms application state into view models\r\n * \r\n * AppObjectPM acts as a mediator between application state (entities) and views.\r\n * It transforms raw application data into a format that's optimized for presentation,\r\n * implementing the presentation model or MVVM pattern.\r\n * \r\n * A PM typically:\r\n * 1. Observes entity changes\r\n * 2. Transforms entity data into view models\r\n * 3. Notifies attached views when view models change\r\n * 4. Handles view model caching and optimization\r\n * \r\n * @typeparam T The view model type this PM produces\r\n */\r\nexport abstract class AppObjectPM<T> extends AppObjectComponent {\r\n /** Identifies this as a Presentation Manager component */\r\n readonly componentType = AppObjectComponentType.PM;\r\n \r\n /**\r\n * Compares two view models to determine if they're equivalent\r\n * Used to prevent unnecessary view updates when the view model hasn't changed\r\n * \r\n * @param a First view model to compare\r\n * @param b Second view model to compare\r\n * @returns True if the view models are considered equal, false otherwise\r\n */\r\n abstract vmsAreEqual(a: T, b: T): boolean;\r\n\r\n /** The most recently generated view model */\r\n private _lastVM?: T;\r\n \r\n /**\r\n * Gets the most recently generated view model\r\n * @returns The last view model or undefined if none has been generated\r\n */\r\n get lastVM(): T | undefined {\r\n return this._lastVM;\r\n }\r\n\r\n /** List of view update functions to notify when the view model changes */\r\n private observerList = new ObserverList<T>();\r\n\r\n /**\r\n * Registers a view update function to be called when the view model changes\r\n * If a view model already exists, the provided function is called immediately with that model\r\n * \r\n * @param updateView Function to call with updated view models\r\n */\r\n addView(updateView: (vm: T) => void): void {\r\n this.observerList.add(updateView);\r\n\r\n // Immediately update the view with current view model if one exists\r\n if (this._lastVM !== undefined) {\r\n updateView(this._lastVM);\r\n }\r\n }\r\n\r\n /**\r\n * Unregisters a previously added view update function\r\n * \r\n * @param updateView The view update function to remove\r\n */\r\n removeView(updateView: (vm: T) => void): void {\r\n this.observerList.remove(updateView);\r\n }\r\n\r\n /**\r\n * Updates the view model and notifies all registered views if the model has changed\r\n * This method should be called by derived classes when the view model needs to be updated\r\n * \r\n * The method performs equality checking to prevent unnecessary updates when\r\n * the new view model is equivalent to the previous one\r\n * \r\n * @param vm The new view model\r\n */\r\n doUpdateView(vm: T) {\r\n // Skip update if the view model hasn't changed\r\n if (this._lastVM && this.vmsAreEqual(this._lastVM, vm)) {\r\n return;\r\n }\r\n\r\n this._lastVM = vm;\r\n this.observerList.notify(vm);\r\n }\r\n\r\n /**\r\n * Cleans up resources and detaches this PM from its parent AppObject\r\n */\r\n dispose() {\r\n this.observerList.clear();\r\n if (this.appObject.getComponent(this.type) === this) {\r\n this.appObject.removeComponent(this.type);\r\n }\r\n super.dispose();\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"AppObjectPM.js","sourceRoot":"","sources":["../../../src/AppObject/AppObjectPM.ts"],"names":[],"mappings":"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","sourcesContent":["import { ObserverList } from \"../Entities\";\r\nimport {\r\n AppObjectComponent,\r\n AppObjectComponentType,\r\n} from \"./AppObjectComponent\";\r\nimport { AppObjectEntity } from \"./AppObjectEntity\";\r\n\r\n/**\r\n * Presentation Manager (PM) component that transforms application state into view models\r\n *\r\n * AppObjectPM acts as a mediator between application state (entities) and views.\r\n * It transforms raw application data into a format that's optimized for presentation,\r\n * implementing the presentation model or MVVM pattern.\r\n *\r\n * A PM typically:\r\n * 1. Observes entity changes\r\n * 2. Transforms entity data into view models\r\n * 3. Notifies attached views when view models change\r\n * 4. Handles view model caching and optimization\r\n *\r\n * @typeparam T The view model type this PM produces\r\n */\r\nexport abstract class AppObjectPM<T> extends AppObjectComponent {\r\n /** Identifies this as a Presentation Manager component */\r\n readonly componentType = AppObjectComponentType.PM;\r\n\r\n /**\r\n * Compares two view models to determine if they're equivalent\r\n * Used to prevent unnecessary view updates when the view model hasn't changed\r\n *\r\n * @param a First view model to compare\r\n * @param b Second view model to compare\r\n * @returns True if the view models are considered equal, false otherwise\r\n */\r\n abstract vmsAreEqual(a: T, b: T): boolean;\r\n\r\n /** The most recently generated view model */\r\n private _lastVM?: T;\r\n\r\n /**\r\n * Optional default view model to return when no view model has been generated yet.\r\n * If set, this value will be returned by the `lastVM` getter before any view model\r\n * has been created via `doUpdateView`.\r\n *\r\n * This is useful for providing initial state to views without requiring immediate\r\n * view model generation.\r\n */\r\n public defaultVM?: T;\r\n\r\n /**\r\n * Gets the most recently generated view model\r\n * @returns The last view model, or `defaultVM` if no view model has been generated yet,\r\n * or undefined if neither exists\r\n */\r\n get lastVM(): T | undefined {\r\n if (!this._lastVM) return this.defaultVM;\r\n return this._lastVM;\r\n }\r\n\r\n /** List of view update functions to notify when the view model changes */\r\n private views = new ObserverList<T>();\r\n\r\n /**\r\n * List of entities being observed by this PM.\r\n * Used for automatic cleanup during disposal.\r\n */\r\n private observedEntities: AppObjectEntity[] = [];\r\n\r\n /**\r\n * Registers a view update function to be called when the view model changes\r\n * If a view model already exists, the provided function is called immediately with that model\r\n *\r\n * @param updateView Function to call with updated view models\r\n */\r\n addView(updateView: (vm: T) => void): void {\r\n if (this.views.length === 0) {\r\n // There are no views yet - generate the initial view model\r\n this.formVM();\r\n }\r\n\r\n this.views.add(updateView);\r\n \r\n // Immediately update the view with current view model if one exists\r\n if (this._lastVM !== undefined) {\r\n updateView(this._lastVM);\r\n }\r\n\r\n this.onViewAdded();\r\n }\r\n\r\n /**\r\n * Called when an observed entity changes.\r\n * If views are registered, this method calls `formVM()` to regenerate the view model.\r\n *\r\n * This method is automatically invoked when entities registered via `observeEntity()`\r\n * notify their observers. It implements lazy evaluation - view models are only\r\n * formed when there are views to receive them.\r\n */\r\n onEntityChanged(): void {\r\n if (this.views.length === 0) {\r\n return;\r\n } else {\r\n this.formVM();\r\n }\r\n }\r\n\r\n /**\r\n * Forms and updates the view model based on current entity state.\r\n *\r\n * Override this method in derived classes to:\r\n * 1. Read data from observed entities\r\n * 2. Transform the data into a view model\r\n * 3. Call `doUpdateView(vm)` with the new view model\r\n *\r\n * This method is only called when at least one view has been registered,\r\n * implementing lazy evaluation to avoid unnecessary computation.\r\n *\r\n * @example\r\n * ```typescript\r\n * formVM(): void {\r\n * const entity = this.getCachedLocalComponent<MyEntity>(MyEntity.type);\r\n * if (entity) {\r\n * this.doUpdateView({\r\n * displayName: entity.name,\r\n * isActive: entity.active\r\n * });\r\n * }\r\n * }\r\n * ```\r\n */\r\n formVM(): void {\r\n // To be implemented by derived classes\r\n // Form up the VM and then call doUpdateView(vm: T)\r\n // This will only be called if at least one view has been registered\r\n }\r\n\r\n onViewAdded(): void {\r\n // Can be overridden by derived classes to react when the first view is added\r\n }\r\n\r\n /**\r\n * Registers an entity to be observed for changes.\r\n *\r\n * When the entity notifies of changes (via `notifyOnChange()`), this PM will\r\n * automatically call `onEntityChanged()`, which in turn calls `formVM()` if\r\n * views are registered.\r\n *\r\n * The entity observer is automatically cleaned up when this PM is disposed.\r\n *\r\n * @param entity The entity to observe for changes\r\n *\r\n * @example\r\n * ```typescript\r\n * constructor(appObj: AppObject) {\r\n * super(appObj, MyPM.type);\r\n * const entity = appObj.getComponent<MyEntity>(MyEntity.type);\r\n * if (entity) {\r\n * this.observeEntity(entity);\r\n * }\r\n * }\r\n * ```\r\n */\r\n protected observeEntity(entity: AppObjectEntity): void {\r\n entity.addChangeObserver(() => {\r\n this.onEntityChanged();\r\n });\r\n\r\n this.observedEntities.push(entity);\r\n }\r\n\r\n /**\r\n * Unregisters a previously added view update function\r\n *\r\n * @param updateView The view update function to remove\r\n */\r\n removeView(updateView: (vm: T) => void): void {\r\n this.views.remove(updateView);\r\n }\r\n\r\n /**\r\n * Updates the view model and notifies all registered views if the model has changed\r\n * This method should be called by derived classes when the view model needs to be updated\r\n *\r\n * The method performs equality checking to prevent unnecessary updates when\r\n * the new view model is equivalent to the previous one\r\n *\r\n * @param vm The new view model\r\n */\r\n doUpdateView(vm: T) {\r\n // Skip update if the view model hasn't changed\r\n if (this._lastVM && this.vmsAreEqual(this._lastVM, vm)) {\r\n return;\r\n }\r\n\r\n this._lastVM = vm;\r\n this.views.notify(vm);\r\n }\r\n\r\n /**\r\n * Cleans up resources and detaches this PM from its parent AppObject\r\n *\r\n * This method:\r\n * 1. Removes change observers from all observed entities\r\n * 2. Clears all view observers\r\n * 3. Removes this component from its parent AppObject if still attached\r\n * 4. Calls the parent class dispose method\r\n */\r\n dispose() {\r\n this.observedEntities.forEach((entity) => {\r\n entity.removeChangeObserver(() => {\r\n this.onEntityChanged();\r\n });\r\n });\r\n\r\n this.views.clear();\r\n if (this.appObject.getComponent(this.type) === this) {\r\n this.appObject.removeComponent(this.type);\r\n }\r\n super.dispose();\r\n }\r\n}\r\n"]}
@@ -122,10 +122,20 @@ class AppObjectRepoImp extends AppObjectRepo {
122
122
  }
123
123
  registerSingleton(component) {
124
124
  if (this.singletons.has(component.type)) {
125
- this.submitWarning("AppObjectRepo", `Singleton for type ${component.type} already exists. Relpacing`);
125
+ this.submitWarning("AppObjectRepo", `Singleton for type ${component.type} already exists. Replacing`);
126
126
  }
127
127
  this.singletons.set(component.type, component);
128
128
  }
129
+ unregisterSingleton(type) {
130
+ this.singletons.delete(type);
131
+ }
132
+ hasSingleton(type) {
133
+ if (this.singletons.has(type)) {
134
+ return true;
135
+ }
136
+ const components = this.getAllComponents(type);
137
+ return components.length === 1;
138
+ }
129
139
  getSingleton(type) {
130
140
  if (this.singletons.has(type)) {
131
141
  return this.singletons.get(type);
@@ -1 +1 @@
1
- {"version":3,"file":"AppObjectRepo.js","sourceRoot":"","sources":["../../../src/AppObject/AppObjectRepo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAa,aAAa,EAAE,MAAM,aAAa,CAAC;AAGvD;;;;;;;;GAQG;AACH,MAAM,OAAgB,aAAc,SAAQ,gBAAgB;CAiK3D;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,IAAI,gBAAgB,EAAE,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACH,MAAM,gBAAiB,SAAQ,aAAa;IAA5C;;QACU,oBAAe,GAAG,IAAI,GAAG,EAAqB,CAAC;QAC/C,eAAU,GAAG,IAAI,GAAG,EAA8B,CAAC;QAEnD,6BAAwB,GAAG,IAAI,YAAY,EAAa,CAAC;QACjE,8BAAyB,GAAG,CAAC,QAA0C,EAAE,EAAE;YACzE,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9C,CAAC,CAAC;QACF,iCAA4B,GAAG,CAC7B,QAA0C,EACpC,EAAE;YACR,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjD,CAAC,CAAC;QAEM,gCAA2B,GAAG,IAAI,YAAY,EAAa,CAAC;QACpE,gCAA2B,GAAG,CAC5B,QAA4C,EAC5C,EAAE;YACF,IAAI,CAAC,2BAA2B,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjD,CAAC,CAAC;QACF,oCAA+B,GAAG,CAChC,QAA4C,EACtC,EAAE;YACR,IAAI,CAAC,2BAA2B,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACpD,CAAC,CAAC;QAEF,QAAG,GAAG,CAAC,EAAU,EAAW,EAAE;YAC5B,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtC,CAAC,CAAC;QAEF,QAAG,GAAG,CAAC,SAAoB,EAAE,EAAE;YAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YACxD,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvC,CAAC;YAED,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;YAClD,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACnC,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,CAAC,CAAC;QAEF,WAAM,GAAG,CAAC,EAAU,EAAE,EAAE;YACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC9C,IAAI,CAAC,QAAQ;gBAAE,OAAO;YAEtB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAChC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrC,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,IAAI,CAAC,2BAA2B,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACpD,CAAC,CAAC;QAEF,QAAG,GAAG,CAAC,EAAU,EAAyB,EAAE;YAC1C,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtC,CAAC,CAAC;QAEF,gBAAW,GAAG,CAAC,EAAU,EAAa,EAAE;YACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAE9C,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACN,OAAO,QAAQ,CAAC;YAClB,CAAC;QACH,CAAC,CAAC;QAEF,WAAM,GAAG,GAAgB,EAAE;YACzB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC;QACnD,CAAC,CAAC;IAsFJ,CAAC;IApFC,6BAA6B,CAAC,aAAqB;QACjD,MAAM,MAAM,GAAgB,EAAE,CAAC;QAE/B,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YACtC,IAAI,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,CAAC;gBACvC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,gBAAgB,CAA+B,IAAY;QACzD,MAAM,MAAM,GAAQ,EAAE,CAAC;QAEvB,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC,QAAa,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,qBAAqB,CACnB,EAAU,EACV,UAAkB;QAElB,MAAM,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO,EAAE,CAAC,YAAY,CAAC,UAAU,CAAM,CAAC;IAC1C,CAAC;IAED,SAAS,CAAC,MAAc,EAAE,OAAe;QACvC,OAAO,CAAC,GAAG,CAAC,IAAI,MAAM,MAAM,OAAO,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,aAAa,CAAC,MAAc,EAAE,OAAe;QAC3C,OAAO,CAAC,IAAI,CAAC,IAAI,MAAM,MAAM,OAAO,EAAE,CAAC,CAAC;IAC1C,CAAC;IACD,WAAW,CAAC,MAAc,EAAE,OAAe;QACzC,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,MAAM,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,WAAW,CAAC,MAAc,EAAE,OAAe;QACzC,OAAO,CAAC,KAAK,CAAC,kBAAkB,MAAM,MAAM,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,iBAAiB,CAAC,SAA6B;QAC7C,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,aAAa,CAChB,eAAe,EACf,sBAAsB,SAAS,CAAC,IAAI,4BAA4B,CACjE,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACjD,CAAC;IAED,YAAY,CAA+B,IAAY;QACrD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAM,CAAC;QACxC,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAqB,IAAI,CAAC,CAAC;QACnE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;YACvD,OAAO,UAAU,CAAC,CAAC,CAAM,CAAC;QAC5B,CAAC;aAAM,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,aAAa,CAChB,eAAe,EACf,kCAAkC,IAAI,EAAE,CACzC,CAAC;YACF,OAAO,SAAS,CAAC;QACnB,CAAC;aAAM,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,aAAa,CAChB,eAAe,EACf,YAAY,IAAI,+EAA+E,CAChG,CAAC;YACF,OAAO,UAAU,CAAC,CAAC,CAAM,CAAC;QAC5B,CAAC;IACH,CAAC;CACF","sourcesContent":["import { ObservableEntity, ObserverList } from \"../Entities\";\r\nimport { AppObject, makeAppObject } from \"./AppObject\";\r\nimport { AppObjectComponent } from \"./AppObjectComponent\";\r\n\r\n/**\r\n * Abstract repository class for managing AppObjects and their components.\r\n *\r\n * This class provides the interface for storing, retrieving, and managing application\r\n * objects, their components, and singletons. It also includes logging functionality\r\n * and observer pattern implementation for tracking changes to the repository.\r\n *\r\n * @extends ObservableEntity\r\n */\r\nexport abstract class AppObjectRepo extends ObservableEntity {\r\n /**\r\n * Checks if an AppObject with the specified ID exists in the repository.\r\n *\r\n * @param {string} appObjectID - The ID of the AppObject to check\r\n * @returns {boolean} True if the AppObject exists, false otherwise\r\n */\r\n abstract has(appObjectID: string): boolean;\r\n\r\n /**\r\n * Adds an AppObject to the repository.\r\n *\r\n * @param {AppObject} appObject - The AppObject to add\r\n */\r\n abstract add(appObject: AppObject): void;\r\n\r\n /**\r\n * Removes an AppObject with the specified ID from the repository.\r\n *\r\n * @param {string} appObjectID - The ID of the AppObject to remove\r\n */\r\n abstract remove(appObjectID: string): void;\r\n\r\n /**\r\n * Gets an AppObject by its ID.\r\n *\r\n * @param {string} appObjectID - The ID of the AppObject to retrieve\r\n * @returns {AppObject | undefined} The AppObject if found, undefined otherwise\r\n */\r\n abstract get(appObjectID: string): AppObject | undefined;\r\n\r\n /**\r\n * Gets an AppObject by its ID, or creates a new one if it doesn't exist.\r\n *\r\n * @param {string} appObjectID - The ID of the AppObject to retrieve or create\r\n * @returns {AppObject} The existing or newly created AppObject\r\n */\r\n abstract getOrCreate(appObjectID: string): AppObject;\r\n\r\n /**\r\n * Gets all AppObjects in the repository.\r\n *\r\n * @returns {AppObject[]} An array of all AppObjects\r\n */\r\n abstract getAll(): AppObject[];\r\n\r\n /**\r\n * Logs an informational message.\r\n *\r\n * @param {string} sender - The identifier of the message sender\r\n * @param {string} message - The message to log\r\n */\r\n abstract submitLog(sender: string, message: string): void;\r\n\r\n /**\r\n * Logs a warning message.\r\n *\r\n * @param {string} sender - The identifier of the message sender\r\n * @param {string} message - The warning message to log\r\n */\r\n abstract submitWarning(sender: string, message: string): void;\r\n\r\n /**\r\n * Logs an error message.\r\n *\r\n * @param {string} sender - The identifier of the message sender\r\n * @param {string} message - The error message to log\r\n */\r\n abstract submitError(sender: string, message: string): void;\r\n\r\n /**\r\n * Logs a fatal error message.\r\n *\r\n * @param {string} sender - The identifier of the message sender\r\n * @param {string} message - The fatal error message to log\r\n */\r\n abstract submitFatal(sender: string, message: string): void;\r\n\r\n /**\r\n * Registers a component as a singleton in the repository.\r\n *\r\n * @param {AppObjectComponent} component - The component to register as a singleton\r\n */\r\n abstract registerSingleton(component: AppObjectComponent): void;\r\n\r\n /**\r\n * Gets a singleton component of the specified type.\r\n *\r\n * @template T - Type of the component to retrieve, must extend AppObjectComponent\r\n * @param {string} type - The type of the singleton to retrieve\r\n * @returns {T | undefined} The singleton component if found, undefined otherwise\r\n */\r\n abstract getSingleton<T extends AppObjectComponent>(\r\n type: string\r\n ): T | undefined;\r\n\r\n /**\r\n * Gets a component of the specified type from an AppObject.\r\n *\r\n * @template T - Type of the component to retrieve, must extend AppObjectComponent\r\n * @param {string} appObjectID - The ID of the AppObject containing the component\r\n * @param {string} type - The type of the component to retrieve\r\n * @returns {T | undefined} The component if found, undefined otherwise\r\n */\r\n abstract getAppObjectComponent<T extends AppObjectComponent>(\r\n appObjectID: string,\r\n type: string\r\n ): T | undefined;\r\n\r\n /**\r\n * Gets all AppObjects that have a component of the specified type.\r\n *\r\n * @param {string} componentType - The component type to filter by\r\n * @returns {AppObject[]} An array of AppObjects having the specified component type\r\n */\r\n abstract getAllAppObjectsWithComponent(componentType: string): AppObject[];\r\n\r\n /**\r\n * Gets all components of the specified type across all AppObjects.\r\n *\r\n * @template T - Type of the components to retrieve, must extend AppObjectComponent\r\n * @param {string} type - The type of components to retrieve\r\n * @returns {T[]} An array of all components of the specified type\r\n */\r\n abstract getAllComponents<T extends AppObjectComponent>(type: string): T[];\r\n\r\n /**\r\n * Adds an observer to be notified when an AppObject is added to the repository.\r\n *\r\n * @param {(addedEntity: AppObject) => void} observer - The observer function\r\n */\r\n abstract addAppObjectAddedObserver: (\r\n observer: (addedEntity: AppObject) => void\r\n ) => void;\r\n\r\n /**\r\n * Removes an observer previously registered for AppObject addition notifications.\r\n *\r\n * @param {(addedEntity: AppObject) => void} observer - The observer function to remove\r\n */\r\n abstract removeAppObjectAddedObserver: (\r\n observer: (addedEntity: AppObject) => void\r\n ) => void;\r\n\r\n /**\r\n * Adds an observer to be notified when an AppObject is removed from the repository.\r\n *\r\n * @param {(addedEntity: AppObject) => void} observer - The observer function\r\n */\r\n abstract addAppObjectRemovedObserver: (\r\n observer: (addedEntity: AppObject) => void\r\n ) => void;\r\n\r\n /**\r\n * Removes an observer previously registered for AppObject removal notifications.\r\n *\r\n * @param {(addedEntity: AppObject) => void} observer - The observer function to remove\r\n */\r\n abstract removedAppObjectRemovedObserver: (\r\n observer: (addedEntity: AppObject) => void\r\n ) => void;\r\n}\r\n\r\n/**\r\n * Creates and returns a new AppObjectRepo instance.\r\n *\r\n * @returns {AppObjectRepo} A new AppObjectRepo instance\r\n */\r\nexport function makeAppObjectRepo(): AppObjectRepo {\r\n return new AppObjectRepoImp();\r\n}\r\n\r\n/**\r\n * Implementation of the AppObjectRepo abstract class.\r\n *\r\n * @private\r\n * @extends AppObjectRepo\r\n */\r\nclass AppObjectRepoImp extends AppObjectRepo {\r\n private appObjectLookup = new Map<string, AppObject>();\r\n private singletons = new Map<string, AppObjectComponent>();\r\n\r\n private onAppObjectAddedObserver = new ObserverList<AppObject>();\r\n addAppObjectAddedObserver = (observer: (addedEntity: AppObject) => void) => {\r\n this.onAppObjectAddedObserver.add(observer);\r\n };\r\n removeAppObjectAddedObserver = (\r\n observer: (addedEntity: AppObject) => void\r\n ): void => {\r\n this.onAppObjectAddedObserver.remove(observer);\r\n };\r\n\r\n private onAppObjectRemovedObservers = new ObserverList<AppObject>();\r\n addAppObjectRemovedObserver = (\r\n observer: (removedEntity: AppObject) => void\r\n ) => {\r\n this.onAppObjectRemovedObservers.add(observer);\r\n };\r\n removedAppObjectRemovedObserver = (\r\n observer: (removedEntity: AppObject) => void\r\n ): void => {\r\n this.onAppObjectRemovedObservers.remove(observer);\r\n };\r\n\r\n has = (id: string): boolean => {\r\n return this.appObjectLookup.has(id);\r\n };\r\n\r\n add = (appObject: AppObject) => {\r\n const existing = this.appObjectLookup.get(appObject.id);\r\n if (existing) {\r\n existing.removeObserver(this.notify);\r\n }\r\n\r\n this.appObjectLookup.set(appObject.id, appObject);\r\n appObject.addObserver(this.notify);\r\n this.notify();\r\n this.onAppObjectAddedObserver.notify(appObject);\r\n };\r\n\r\n remove = (id: string) => {\r\n const existing = this.appObjectLookup.get(id);\r\n if (!existing) return;\r\n\r\n this.appObjectLookup.delete(id);\r\n existing.removeObserver(this.notify);\r\n this.notify();\r\n this.onAppObjectRemovedObservers.notify(existing);\r\n };\r\n\r\n get = (id: string): AppObject | undefined => {\r\n return this.appObjectLookup.get(id);\r\n };\r\n\r\n getOrCreate = (id: string): AppObject => {\r\n const existing = this.appObjectLookup.get(id);\r\n\r\n if (!existing) {\r\n return makeAppObject(id, this);\r\n } else {\r\n return existing;\r\n }\r\n };\r\n\r\n getAll = (): AppObject[] => {\r\n return Array.from(this.appObjectLookup.values());\r\n };\r\n\r\n getAllAppObjectsWithComponent(componentType: string): AppObject[] {\r\n const rArray: AppObject[] = [];\r\n\r\n this.appObjectLookup.forEach((appObj) => {\r\n if (appObj.hasComponent(componentType)) {\r\n rArray.push(appObj);\r\n }\r\n });\r\n\r\n return rArray;\r\n }\r\n\r\n getAllComponents<T extends AppObjectComponent>(type: string): T[] {\r\n const rArray: T[] = [];\r\n\r\n this.appObjectLookup.forEach((appObj) => {\r\n const aoEntity = appObj.getComponent(type);\r\n if (aoEntity) {\r\n rArray.push(aoEntity as T);\r\n }\r\n });\r\n\r\n return rArray;\r\n }\r\n\r\n getAppObjectComponent<T extends AppObjectComponent>(\r\n id: string,\r\n entityType: string\r\n ): T | undefined {\r\n const ao = this.appObjectLookup.get(id);\r\n if (!ao) {\r\n return undefined;\r\n }\r\n\r\n return ao.getComponent(entityType) as T;\r\n }\r\n\r\n submitLog(sender: string, message: string): void {\r\n console.log(`[${sender}]: ${message}`);\r\n }\r\n submitWarning(sender: string, message: string): void {\r\n console.warn(`[${sender}]: ${message}`);\r\n }\r\n submitError(sender: string, message: string): void {\r\n console.error(`[${sender}]: ${message}`);\r\n }\r\n submitFatal(sender: string, message: string): void {\r\n console.error(`FATAL ERROR - [${sender}]: ${message}`);\r\n }\r\n\r\n registerSingleton(component: AppObjectComponent): void {\r\n if (this.singletons.has(component.type)) {\r\n this.submitWarning(\r\n \"AppObjectRepo\",\r\n `Singleton for type ${component.type} already exists. Relpacing`\r\n );\r\n }\r\n\r\n this.singletons.set(component.type, component);\r\n }\r\n\r\n getSingleton<T extends AppObjectComponent>(type: string): T | undefined {\r\n if (this.singletons.has(type)) {\r\n return this.singletons.get(type) as T;\r\n }\r\n\r\n const components = this.getAllComponents<AppObjectComponent>(type);\r\n if (components.length === 1) {\r\n this.singletons.set(components[0].type, components[0]);\r\n return components[0] as T;\r\n } else if (components.length === 0) {\r\n this.submitWarning(\r\n \"AppObjectRepo\",\r\n `Unable to find a singleton for ${type}`\r\n );\r\n return undefined;\r\n } else if (components.length > 1) {\r\n this.submitWarning(\r\n \"AppObjectRepo\",\r\n `Multiple ${type} found. There should only be one if it truly a singleton. Using the first one`\r\n );\r\n return components[0] as T;\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"AppObjectRepo.js","sourceRoot":"","sources":["../../../src/AppObject/AppObjectRepo.ts"],"names":[],"mappings":"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","sourcesContent":["import { ObservableEntity, ObserverList } from \"../Entities\";\r\nimport { AppObject, makeAppObject } from \"./AppObject\";\r\nimport { AppObjectComponent } from \"./AppObjectComponent\";\r\n\r\n/**\r\n * Abstract repository class for managing AppObjects and their components.\r\n *\r\n * This class provides the interface for storing, retrieving, and managing application\r\n * objects, their components, and singletons. It also includes logging functionality\r\n * and observer pattern implementation for tracking changes to the repository.\r\n *\r\n * @extends ObservableEntity\r\n */\r\nexport abstract class AppObjectRepo extends ObservableEntity {\r\n /**\r\n * Checks if an AppObject with the specified ID exists in the repository.\r\n *\r\n * @param {string} appObjectID - The ID of the AppObject to check\r\n * @returns {boolean} True if the AppObject exists, false otherwise\r\n */\r\n abstract has(appObjectID: string): boolean;\r\n\r\n /**\r\n * Adds an AppObject to the repository.\r\n *\r\n * @param {AppObject} appObject - The AppObject to add\r\n */\r\n abstract add(appObject: AppObject): void;\r\n\r\n /**\r\n * Removes an AppObject with the specified ID from the repository.\r\n *\r\n * @param {string} appObjectID - The ID of the AppObject to remove\r\n */\r\n abstract remove(appObjectID: string): void;\r\n\r\n /**\r\n * Gets an AppObject by its ID.\r\n *\r\n * @param {string} appObjectID - The ID of the AppObject to retrieve\r\n * @returns {AppObject | undefined} The AppObject if found, undefined otherwise\r\n */\r\n abstract get(appObjectID: string): AppObject | undefined;\r\n\r\n /**\r\n * Gets an AppObject by its ID, or creates a new one if it doesn't exist.\r\n *\r\n * @param {string} appObjectID - The ID of the AppObject to retrieve or create\r\n * @returns {AppObject} The existing or newly created AppObject\r\n */\r\n abstract getOrCreate(appObjectID: string): AppObject;\r\n\r\n /**\r\n * Gets all AppObjects in the repository.\r\n *\r\n * @returns {AppObject[]} An array of all AppObjects\r\n */\r\n abstract getAll(): AppObject[];\r\n\r\n /**\r\n * Logs an informational message.\r\n *\r\n * @param {string} sender - The identifier of the message sender\r\n * @param {string} message - The message to log\r\n */\r\n abstract submitLog(sender: string, message: string): void;\r\n\r\n /**\r\n * Logs a warning message.\r\n *\r\n * @param {string} sender - The identifier of the message sender\r\n * @param {string} message - The warning message to log\r\n */\r\n abstract submitWarning(sender: string, message: string): void;\r\n\r\n /**\r\n * Logs an error message.\r\n *\r\n * @param {string} sender - The identifier of the message sender\r\n * @param {string} message - The error message to log\r\n */\r\n abstract submitError(sender: string, message: string): void;\r\n\r\n /**\r\n * Logs a fatal error message.\r\n *\r\n * @param {string} sender - The identifier of the message sender\r\n * @param {string} message - The fatal error message to log\r\n */\r\n abstract submitFatal(sender: string, message: string): void;\r\n\r\n /**\r\n * Registers a component as a singleton in the repository.\r\n *\r\n * @param {AppObjectComponent} component - The component to register as a singleton\r\n */\r\n abstract registerSingleton(component: AppObjectComponent): void;\r\n\r\n /**\r\n * Unregisters a singleton component from the repository.\r\n *\r\n * @param {string} type - The type of the singleton to unregister\r\n */\r\n abstract unregisterSingleton(type: string): void;\r\n\r\n /**\r\n * Checks if a singleton component of the specified type exists.\r\n *\r\n * @param {string} type - The type of the singleton to check\r\n * @returns {boolean} True if a singleton of the specified type exists, false otherwise\r\n */\r\n abstract hasSingleton(type: string): boolean;\r\n\r\n /**\r\n * Gets a singleton component of the specified type.\r\n *\r\n * @template T - Type of the component to retrieve, must extend AppObjectComponent\r\n * @param {string} type - The type of the singleton to retrieve\r\n * @returns {T | undefined} The singleton component if found, undefined otherwise\r\n */\r\n abstract getSingleton<T extends AppObjectComponent>(\r\n type: string\r\n ): T | undefined;\r\n\r\n /**\r\n * Gets a component of the specified type from an AppObject.\r\n *\r\n * @template T - Type of the component to retrieve, must extend AppObjectComponent\r\n * @param {string} appObjectID - The ID of the AppObject containing the component\r\n * @param {string} type - The type of the component to retrieve\r\n * @returns {T | undefined} The component if found, undefined otherwise\r\n */\r\n abstract getAppObjectComponent<T extends AppObjectComponent>(\r\n appObjectID: string,\r\n type: string\r\n ): T | undefined;\r\n\r\n /**\r\n * Gets all AppObjects that have a component of the specified type.\r\n *\r\n * @param {string} componentType - The component type to filter by\r\n * @returns {AppObject[]} An array of AppObjects having the specified component type\r\n */\r\n abstract getAllAppObjectsWithComponent(componentType: string): AppObject[];\r\n\r\n /**\r\n * Gets all components of the specified type across all AppObjects.\r\n *\r\n * @template T - Type of the components to retrieve, must extend AppObjectComponent\r\n * @param {string} type - The type of components to retrieve\r\n * @returns {T[]} An array of all components of the specified type\r\n */\r\n abstract getAllComponents<T extends AppObjectComponent>(type: string): T[];\r\n\r\n /**\r\n * Adds an observer to be notified when an AppObject is added to the repository.\r\n *\r\n * @param {(addedEntity: AppObject) => void} observer - The observer function\r\n */\r\n abstract addAppObjectAddedObserver: (\r\n observer: (addedEntity: AppObject) => void\r\n ) => void;\r\n\r\n /**\r\n * Removes an observer previously registered for AppObject addition notifications.\r\n *\r\n * @param {(addedEntity: AppObject) => void} observer - The observer function to remove\r\n */\r\n abstract removeAppObjectAddedObserver: (\r\n observer: (addedEntity: AppObject) => void\r\n ) => void;\r\n\r\n /**\r\n * Adds an observer to be notified when an AppObject is removed from the repository.\r\n *\r\n * @param {(addedEntity: AppObject) => void} observer - The observer function\r\n */\r\n abstract addAppObjectRemovedObserver: (\r\n observer: (addedEntity: AppObject) => void\r\n ) => void;\r\n\r\n /**\r\n * Removes an observer previously registered for AppObject removal notifications.\r\n *\r\n * @param {(addedEntity: AppObject) => void} observer - The observer function to remove\r\n */\r\n abstract removedAppObjectRemovedObserver: (\r\n observer: (addedEntity: AppObject) => void\r\n ) => void;\r\n}\r\n\r\n/**\r\n * Creates and returns a new AppObjectRepo instance.\r\n *\r\n * @returns {AppObjectRepo} A new AppObjectRepo instance\r\n */\r\nexport function makeAppObjectRepo(): AppObjectRepo {\r\n return new AppObjectRepoImp();\r\n}\r\n\r\n/**\r\n * Implementation of the AppObjectRepo abstract class.\r\n *\r\n * @private\r\n * @extends AppObjectRepo\r\n */\r\nclass AppObjectRepoImp extends AppObjectRepo {\r\n private appObjectLookup = new Map<string, AppObject>();\r\n private singletons = new Map<string, AppObjectComponent>();\r\n\r\n private onAppObjectAddedObserver = new ObserverList<AppObject>();\r\n addAppObjectAddedObserver = (observer: (addedEntity: AppObject) => void) => {\r\n this.onAppObjectAddedObserver.add(observer);\r\n };\r\n removeAppObjectAddedObserver = (\r\n observer: (addedEntity: AppObject) => void\r\n ): void => {\r\n this.onAppObjectAddedObserver.remove(observer);\r\n };\r\n\r\n private onAppObjectRemovedObservers = new ObserverList<AppObject>();\r\n addAppObjectRemovedObserver = (\r\n observer: (removedEntity: AppObject) => void\r\n ) => {\r\n this.onAppObjectRemovedObservers.add(observer);\r\n };\r\n removedAppObjectRemovedObserver = (\r\n observer: (removedEntity: AppObject) => void\r\n ): void => {\r\n this.onAppObjectRemovedObservers.remove(observer);\r\n };\r\n\r\n has = (id: string): boolean => {\r\n return this.appObjectLookup.has(id);\r\n };\r\n\r\n add = (appObject: AppObject) => {\r\n const existing = this.appObjectLookup.get(appObject.id);\r\n if (existing) {\r\n existing.removeObserver(this.notify);\r\n }\r\n\r\n this.appObjectLookup.set(appObject.id, appObject);\r\n appObject.addObserver(this.notify);\r\n this.notify();\r\n this.onAppObjectAddedObserver.notify(appObject);\r\n };\r\n\r\n remove = (id: string) => {\r\n const existing = this.appObjectLookup.get(id);\r\n if (!existing) return;\r\n\r\n this.appObjectLookup.delete(id);\r\n existing.removeObserver(this.notify);\r\n this.notify();\r\n this.onAppObjectRemovedObservers.notify(existing);\r\n };\r\n\r\n get = (id: string): AppObject | undefined => {\r\n return this.appObjectLookup.get(id);\r\n };\r\n\r\n getOrCreate = (id: string): AppObject => {\r\n const existing = this.appObjectLookup.get(id);\r\n\r\n if (!existing) {\r\n return makeAppObject(id, this);\r\n } else {\r\n return existing;\r\n }\r\n };\r\n\r\n getAll = (): AppObject[] => {\r\n return Array.from(this.appObjectLookup.values());\r\n };\r\n\r\n getAllAppObjectsWithComponent(componentType: string): AppObject[] {\r\n const rArray: AppObject[] = [];\r\n\r\n this.appObjectLookup.forEach((appObj) => {\r\n if (appObj.hasComponent(componentType)) {\r\n rArray.push(appObj);\r\n }\r\n });\r\n\r\n return rArray;\r\n }\r\n\r\n getAllComponents<T extends AppObjectComponent>(type: string): T[] {\r\n const rArray: T[] = [];\r\n\r\n this.appObjectLookup.forEach((appObj) => {\r\n const aoEntity = appObj.getComponent(type);\r\n if (aoEntity) {\r\n rArray.push(aoEntity as T);\r\n }\r\n });\r\n\r\n return rArray;\r\n }\r\n\r\n getAppObjectComponent<T extends AppObjectComponent>(\r\n id: string,\r\n entityType: string\r\n ): T | undefined {\r\n const ao = this.appObjectLookup.get(id);\r\n if (!ao) {\r\n return undefined;\r\n }\r\n\r\n return ao.getComponent(entityType) as T;\r\n }\r\n\r\n submitLog(sender: string, message: string): void {\r\n console.log(`[${sender}]: ${message}`);\r\n }\r\n submitWarning(sender: string, message: string): void {\r\n console.warn(`[${sender}]: ${message}`);\r\n }\r\n submitError(sender: string, message: string): void {\r\n console.error(`[${sender}]: ${message}`);\r\n }\r\n submitFatal(sender: string, message: string): void {\r\n console.error(`FATAL ERROR - [${sender}]: ${message}`);\r\n }\r\n\r\n registerSingleton(component: AppObjectComponent): void {\r\n if (this.singletons.has(component.type)) {\r\n this.submitWarning(\r\n \"AppObjectRepo\",\r\n `Singleton for type ${component.type} already exists. Replacing`\r\n );\r\n }\r\n\r\n this.singletons.set(component.type, component);\r\n }\r\n\r\n unregisterSingleton(type: string): void {\r\n this.singletons.delete(type);\r\n }\r\n\r\n hasSingleton(type: string): boolean {\r\n if (this.singletons.has(type)) {\r\n return true;\r\n }\r\n\r\n const components = this.getAllComponents<AppObjectComponent>(type);\r\n return components.length === 1;\r\n }\r\n\r\n getSingleton<T extends AppObjectComponent>(type: string): T | undefined {\r\n if (this.singletons.has(type)) {\r\n return this.singletons.get(type) as T;\r\n }\r\n\r\n const components = this.getAllComponents<AppObjectComponent>(type);\r\n if (components.length === 1) {\r\n this.singletons.set(components[0].type, components[0]);\r\n return components[0] as T;\r\n } else if (components.length === 0) {\r\n this.submitWarning(\r\n \"AppObjectRepo\",\r\n `Unable to find a singleton for ${type}`\r\n );\r\n return undefined;\r\n } else if (components.length > 1) {\r\n this.submitWarning(\r\n \"AppObjectRepo\",\r\n `Multiple ${type} found. There should only be one if it truly a singleton. Using the first one`\r\n );\r\n return components[0] as T;\r\n }\r\n }\r\n}\r\n"]}
@@ -0,0 +1,36 @@
1
+ import { AppObjectEntity } from "./AppObjectEntity";
2
+ /**
3
+ * Singleton entity component that manages application state
4
+ *
5
+ * AppObjectSingletonEntity extends AppObjectEntity and automatically registers itself
6
+ * as a singleton in the AppObjectRepo upon construction. This ensures only one instance
7
+ * of this entity type exists across the entire application.
8
+ *
9
+ * Use this class when you need an entity that should have only one instance globally,
10
+ * such as application-wide configuration or shared state managers.
11
+ */
12
+ export class AppObjectSingletonEntity extends AppObjectEntity {
13
+ /**
14
+ * Creates a new singleton entity component and attaches it to the specified AppObject
15
+ * Automatically registers itself as a singleton in the AppObjectRepo
16
+ *
17
+ * @param appObject The parent AppObject this component will be attached to
18
+ * @param type The unique type identifier for this component
19
+ */
20
+ constructor(appObject, type) {
21
+ super(appObject, type);
22
+ this.appObjects.registerSingleton(this);
23
+ }
24
+ /**
25
+ * Cleans up resources and unregisters the singleton
26
+ *
27
+ * This method:
28
+ * 1. Unregisters itself from the singleton registry
29
+ * 2. Calls the parent class dispose method
30
+ */
31
+ dispose() {
32
+ this.appObjects.unregisterSingleton(this.type);
33
+ super.dispose();
34
+ }
35
+ }
36
+ //# sourceMappingURL=AppObjectSingletonEntity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppObjectSingletonEntity.js","sourceRoot":"","sources":["../../../src/AppObject/AppObjectSingletonEntity.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;;;;;GASG;AACH,MAAM,OAAO,wBAAyB,SAAQ,eAAe;IAC3D;;;;;;OAMG;IACH,YAAY,SAAoB,EAAE,IAAY;QAC5C,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAEvB,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;;OAMG;IACH,OAAO;QACL,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;CACF","sourcesContent":["import { AppObject } from \"./AppObject\";\r\nimport { AppObjectEntity } from \"./AppObjectEntity\";\r\n\r\n/**\r\n * Singleton entity component that manages application state\r\n *\r\n * AppObjectSingletonEntity extends AppObjectEntity and automatically registers itself\r\n * as a singleton in the AppObjectRepo upon construction. This ensures only one instance\r\n * of this entity type exists across the entire application.\r\n *\r\n * Use this class when you need an entity that should have only one instance globally,\r\n * such as application-wide configuration or shared state managers.\r\n */\r\nexport class AppObjectSingletonEntity extends AppObjectEntity {\r\n /**\r\n * Creates a new singleton entity component and attaches it to the specified AppObject\r\n * Automatically registers itself as a singleton in the AppObjectRepo\r\n *\r\n * @param appObject The parent AppObject this component will be attached to\r\n * @param type The unique type identifier for this component\r\n */\r\n constructor(appObject: AppObject, type: string) {\r\n super(appObject, type);\r\n\r\n this.appObjects.registerSingleton(this);\r\n }\r\n\r\n /**\r\n * Cleans up resources and unregisters the singleton\r\n *\r\n * This method:\r\n * 1. Unregisters itself from the singleton registry\r\n * 2. Calls the parent class dispose method\r\n */\r\n dispose() {\r\n this.appObjects.unregisterSingleton(this.type);\r\n super.dispose();\r\n }\r\n}\r\n"]}
@@ -0,0 +1,50 @@
1
+ import { AppObjectEntityRepo } from "./AppObjectEntityRepo";
2
+ /**
3
+ * A singleton repository for managing collections of AppObjectEntity instances.
4
+ *
5
+ * This generic class extends AppObjectEntityRepo and automatically registers itself
6
+ * as a singleton in the AppObjectRepo upon construction. This ensures only one instance
7
+ * of this repository type exists across the entire application.
8
+ *
9
+ * Use this class when you need a centralized repository that should have only one instance
10
+ * globally, such as application-wide entity collections or shared resource managers.
11
+ *
12
+ * @template T - The type of entities managed by this repository, must extend AppObjectEntity
13
+ * @extends AppObjectEntityRepo
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // Create a singleton repository for player entities
18
+ * class PlayerRepo extends AppObjectSingletonEntityRepo<PlayerEntity> {
19
+ * static type = "playerRepo";
20
+ * constructor(appObject: AppObject) {
21
+ * super(appObject, PlayerRepo.type);
22
+ * }
23
+ * }
24
+ * ```
25
+ */
26
+ export class AppObjectSingletonEntityRepo extends AppObjectEntityRepo {
27
+ /**
28
+ * Creates a new singleton entity repository component and attaches it to the specified AppObject
29
+ * Automatically registers itself as a singleton in the AppObjectRepo
30
+ *
31
+ * @param appObject The parent AppObject this component will be attached to
32
+ * @param type The unique type identifier for this component
33
+ */
34
+ constructor(appObject, type) {
35
+ super(appObject, type);
36
+ this.appObjects.registerSingleton(this);
37
+ }
38
+ /**
39
+ * Cleans up resources and unregisters the singleton
40
+ *
41
+ * This method:
42
+ * 1. Unregisters itself from the singleton registry
43
+ * 2. Calls the parent class dispose method
44
+ */
45
+ dispose() {
46
+ this.appObjects.unregisterSingleton(this.type);
47
+ super.dispose();
48
+ }
49
+ }
50
+ //# sourceMappingURL=AppObjectSingletonEntityRepo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppObjectSingletonEntityRepo.js","sourceRoot":"","sources":["../../../src/AppObject/AppObjectSingletonEntityRepo.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,OAAO,4BAEX,SAAQ,mBAAsB;IAC9B;;;;;;OAMG;IACH,YAAY,SAAoB,EAAE,IAAY;QAC5C,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAEvB,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;;OAMG;IACH,OAAO;QACL,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;CACF","sourcesContent":["import { AppObject } from \"./AppObject\";\r\nimport { AppObjectEntity } from \"./AppObjectEntity\";\r\nimport { AppObjectEntityRepo } from \"./AppObjectEntityRepo\";\r\n\r\n/**\r\n * A singleton repository for managing collections of AppObjectEntity instances.\r\n *\r\n * This generic class extends AppObjectEntityRepo and automatically registers itself\r\n * as a singleton in the AppObjectRepo upon construction. This ensures only one instance\r\n * of this repository type exists across the entire application.\r\n *\r\n * Use this class when you need a centralized repository that should have only one instance\r\n * globally, such as application-wide entity collections or shared resource managers.\r\n *\r\n * @template T - The type of entities managed by this repository, must extend AppObjectEntity\r\n * @extends AppObjectEntityRepo\r\n *\r\n * @example\r\n * ```typescript\r\n * // Create a singleton repository for player entities\r\n * class PlayerRepo extends AppObjectSingletonEntityRepo<PlayerEntity> {\r\n * static type = \"playerRepo\";\r\n * constructor(appObject: AppObject) {\r\n * super(appObject, PlayerRepo.type);\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport class AppObjectSingletonEntityRepo<\r\n T extends AppObjectEntity,\r\n> extends AppObjectEntityRepo<T> {\r\n /**\r\n * Creates a new singleton entity repository component and attaches it to the specified AppObject\r\n * Automatically registers itself as a singleton in the AppObjectRepo\r\n *\r\n * @param appObject The parent AppObject this component will be attached to\r\n * @param type The unique type identifier for this component\r\n */\r\n constructor(appObject: AppObject, type: string) {\r\n super(appObject, type);\r\n\r\n this.appObjects.registerSingleton(this);\r\n }\r\n\r\n /**\r\n * Cleans up resources and unregisters the singleton\r\n *\r\n * This method:\r\n * 1. Unregisters itself from the singleton registry\r\n * 2. Calls the parent class dispose method\r\n */\r\n dispose() {\r\n this.appObjects.unregisterSingleton(this.type);\r\n super.dispose();\r\n }\r\n}\r\n"]}
@@ -0,0 +1,65 @@
1
+ import { AppObjectPM } from "./AppObjectPM";
2
+ /**
3
+ * Singleton Presentation Manager (PM) component that transforms application state into view models
4
+ *
5
+ * AppObjectSingletonPM extends AppObjectPM and automatically registers itself as a singleton
6
+ * in the AppObjectRepo upon construction. This ensures only one instance of this PM type exists
7
+ * across the entire application.
8
+ *
9
+ * Use this class when you need a presentation manager that should have only one instance globally,
10
+ * such as application-wide UI state managers or shared view model providers.
11
+ *
12
+ * A singleton PM typically:
13
+ * 1. Observes entity changes
14
+ * 2. Transforms entity data into view models
15
+ * 3. Notifies attached views when view models change
16
+ * 4. Handles view model caching and optimization
17
+ * 5. Exists as a single instance across the application
18
+ *
19
+ * @typeparam T The view model type this PM produces
20
+ * @extends AppObjectPM
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * class GlobalSettingsPM extends AppObjectSingletonPM<SettingsVM> {
25
+ * static type = "globalSettingsPM";
26
+ *
27
+ * constructor(appObject: AppObject) {
28
+ * super(appObject, GlobalSettingsPM.type);
29
+ * }
30
+ *
31
+ * vmsAreEqual(a: SettingsVM, b: SettingsVM): boolean {
32
+ * return a.theme === b.theme && a.language === b.language;
33
+ * }
34
+ *
35
+ * formVM(): void {
36
+ * // Form view model from entities
37
+ * }
38
+ * }
39
+ * ```
40
+ */
41
+ export class AppObjectSingletonPM extends AppObjectPM {
42
+ /**
43
+ * Creates a new singleton presentation manager component and attaches it to the specified AppObject
44
+ * Automatically registers itself as a singleton in the AppObjectRepo
45
+ *
46
+ * @param appObject The parent AppObject this component will be attached to
47
+ * @param type The unique type identifier for this component
48
+ */
49
+ constructor(appObject, type) {
50
+ super(appObject, type);
51
+ this.appObjects.registerSingleton(this);
52
+ }
53
+ /**
54
+ * Cleans up resources and unregisters the singleton
55
+ *
56
+ * This method:
57
+ * 1. Unregisters itself from the singleton registry
58
+ * 2. Calls the parent class dispose method (which handles entity observers and views)
59
+ */
60
+ dispose() {
61
+ this.appObjects.unregisterSingleton(this.type);
62
+ super.dispose();
63
+ }
64
+ }
65
+ //# sourceMappingURL=AppObjectSingletonPM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppObjectSingletonPM.js","sourceRoot":"","sources":["../../../src/AppObject/AppObjectSingletonPM.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,OAAgB,oBAAwB,SAAQ,WAAc;IAClE;;;;;;OAMG;IACH,YAAY,SAAoB,EAAE,IAAY;QAC5C,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAEvB,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;;OAMG;IACH,OAAO;QACL,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;CACF","sourcesContent":["import { AppObject } from \"./AppObject\";\r\nimport { AppObjectPM } from \"./AppObjectPM\";\r\n\r\n/**\r\n * Singleton Presentation Manager (PM) component that transforms application state into view models\r\n *\r\n * AppObjectSingletonPM extends AppObjectPM and automatically registers itself as a singleton\r\n * in the AppObjectRepo upon construction. This ensures only one instance of this PM type exists\r\n * across the entire application.\r\n *\r\n * Use this class when you need a presentation manager that should have only one instance globally,\r\n * such as application-wide UI state managers or shared view model providers.\r\n *\r\n * A singleton PM typically:\r\n * 1. Observes entity changes\r\n * 2. Transforms entity data into view models\r\n * 3. Notifies attached views when view models change\r\n * 4. Handles view model caching and optimization\r\n * 5. Exists as a single instance across the application\r\n *\r\n * @typeparam T The view model type this PM produces\r\n * @extends AppObjectPM\r\n *\r\n * @example\r\n * ```typescript\r\n * class GlobalSettingsPM extends AppObjectSingletonPM<SettingsVM> {\r\n * static type = \"globalSettingsPM\";\r\n *\r\n * constructor(appObject: AppObject) {\r\n * super(appObject, GlobalSettingsPM.type);\r\n * }\r\n *\r\n * vmsAreEqual(a: SettingsVM, b: SettingsVM): boolean {\r\n * return a.theme === b.theme && a.language === b.language;\r\n * }\r\n *\r\n * formVM(): void {\r\n * // Form view model from entities\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport abstract class AppObjectSingletonPM<T> extends AppObjectPM<T> {\r\n /**\r\n * Creates a new singleton presentation manager component and attaches it to the specified AppObject\r\n * Automatically registers itself as a singleton in the AppObjectRepo\r\n *\r\n * @param appObject The parent AppObject this component will be attached to\r\n * @param type The unique type identifier for this component\r\n */\r\n constructor(appObject: AppObject, type: string) {\r\n super(appObject, type);\r\n\r\n this.appObjects.registerSingleton(this);\r\n }\r\n\r\n /**\r\n * Cleans up resources and unregisters the singleton\r\n *\r\n * This method:\r\n * 1. Unregisters itself from the singleton registry\r\n * 2. Calls the parent class dispose method (which handles entity observers and views)\r\n */\r\n dispose() {\r\n this.appObjects.unregisterSingleton(this.type);\r\n super.dispose();\r\n }\r\n}\r\n"]}
@@ -0,0 +1,56 @@
1
+ import { AppObjectUC } from "./AppObjectUC";
2
+ /**
3
+ * AppObjectSingletonUC (Use Case) serves as a singleton use case class within the application framework.
4
+ *
5
+ * This class extends AppObjectUC and automatically registers itself as a singleton in the
6
+ * AppObjectRepo upon construction. This ensures only one instance of this use case type exists
7
+ * across the entire application.
8
+ *
9
+ * Use Cases are components that represent specific application operations or workflows.
10
+ * They encapsulate business rules and coordinate interactions between different parts
11
+ * of the application. Use this singleton version when the use case should exist as a
12
+ * single instance globally, such as application-wide orchestration or workflow managers.
13
+ *
14
+ * @extends AppObjectUC
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * class GlobalPurchaseManagerUC extends AppObjectSingletonUC {
19
+ * static type = "globalPurchaseManagerUC";
20
+ *
21
+ * constructor(appObject: AppObject) {
22
+ * super(appObject, GlobalPurchaseManagerUC.type);
23
+ * }
24
+ *
25
+ * execute(itemId: string, quantity: number): boolean {
26
+ * // Implement the purchase item use case
27
+ * return true; // if successful
28
+ * }
29
+ * }
30
+ * ```
31
+ */
32
+ export class AppObjectSingletonUC extends AppObjectUC {
33
+ /**
34
+ * Creates a new singleton use case component and attaches it to the specified AppObject
35
+ * Automatically registers itself as a singleton in the AppObjectRepo
36
+ *
37
+ * @param appObject The parent AppObject this component will be attached to
38
+ * @param type The unique type identifier for this component
39
+ */
40
+ constructor(appObject, type) {
41
+ super(appObject, type);
42
+ this.appObjects.registerSingleton(this);
43
+ }
44
+ /**
45
+ * Cleans up resources and unregisters the singleton
46
+ *
47
+ * This method:
48
+ * 1. Unregisters itself from the singleton registry
49
+ * 2. Calls the parent class dispose method
50
+ */
51
+ dispose() {
52
+ this.appObjects.unregisterSingleton(this.type);
53
+ super.dispose();
54
+ }
55
+ }
56
+ //# sourceMappingURL=AppObjectSingletonUC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppObjectSingletonUC.js","sourceRoot":"","sources":["../../../src/AppObject/AppObjectSingletonUC.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,OAAO,oBAAqB,SAAQ,WAAW;IACnD;;;;;;OAMG;IACH,YAAY,SAAoB,EAAE,IAAY;QAC5C,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAEvB,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;;OAMG;IACH,OAAO;QACL,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;CACF","sourcesContent":["import { AppObject } from \"./AppObject\";\r\nimport { AppObjectUC } from \"./AppObjectUC\";\r\n\r\n/**\r\n * AppObjectSingletonUC (Use Case) serves as a singleton use case class within the application framework.\r\n *\r\n * This class extends AppObjectUC and automatically registers itself as a singleton in the\r\n * AppObjectRepo upon construction. This ensures only one instance of this use case type exists\r\n * across the entire application.\r\n *\r\n * Use Cases are components that represent specific application operations or workflows.\r\n * They encapsulate business rules and coordinate interactions between different parts\r\n * of the application. Use this singleton version when the use case should exist as a\r\n * single instance globally, such as application-wide orchestration or workflow managers.\r\n *\r\n * @extends AppObjectUC\r\n *\r\n * @example\r\n * ```typescript\r\n * class GlobalPurchaseManagerUC extends AppObjectSingletonUC {\r\n * static type = \"globalPurchaseManagerUC\";\r\n *\r\n * constructor(appObject: AppObject) {\r\n * super(appObject, GlobalPurchaseManagerUC.type);\r\n * }\r\n *\r\n * execute(itemId: string, quantity: number): boolean {\r\n * // Implement the purchase item use case\r\n * return true; // if successful\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport class AppObjectSingletonUC extends AppObjectUC {\r\n /**\r\n * Creates a new singleton use case component and attaches it to the specified AppObject\r\n * Automatically registers itself as a singleton in the AppObjectRepo\r\n *\r\n * @param appObject The parent AppObject this component will be attached to\r\n * @param type The unique type identifier for this component\r\n */\r\n constructor(appObject: AppObject, type: string) {\r\n super(appObject, type);\r\n\r\n this.appObjects.registerSingleton(this);\r\n }\r\n\r\n /**\r\n * Cleans up resources and unregisters the singleton\r\n *\r\n * This method:\r\n * 1. Unregisters itself from the singleton registry\r\n * 2. Calls the parent class dispose method\r\n */\r\n dispose() {\r\n this.appObjects.unregisterSingleton(this.type);\r\n super.dispose();\r\n }\r\n}\r\n"]}
@@ -6,6 +6,10 @@ export * from "./AppObjectRepo";
6
6
  export * from "./AppObjectUC";
7
7
  export * from "./AppObjectController";
8
8
  export * from "./AppObjectView";
9
+ export * from "./AppObjectSingletonEntity";
10
+ export * from "./AppObjectSingletonEntityRepo";
11
+ export * from "./AppObjectSingletonPM";
12
+ export * from "./AppObjectSingletonUC";
9
13
  export * from "./getSingletonComponent";
10
14
  export * from "./printAppObjectDetails";
11
15
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/AppObject/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC","sourcesContent":["export * from \"./AppObject\"\r\nexport * from \"./AppObjectEntity\"\r\nexport * from \"./AppObjectEntityRepo\"\r\nexport * from \"./AppObjectPM\"\r\nexport * from \"./AppObjectRepo\"\r\nexport * from \"./AppObjectUC\"\r\nexport * from \"./AppObjectController\"\r\nexport * from \"./AppObjectView\"\r\nexport * from \"./getSingletonComponent\";\r\nexport * from \"./printAppObjectDetails\";"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/AppObject/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC","sourcesContent":["export * from \"./AppObject\";\r\nexport * from \"./AppObjectEntity\";\r\nexport * from \"./AppObjectEntityRepo\";\r\nexport * from \"./AppObjectPM\";\r\nexport * from \"./AppObjectRepo\";\r\nexport * from \"./AppObjectUC\";\r\nexport * from \"./AppObjectController\";\r\nexport * from \"./AppObjectView\";\r\nexport * from \"./AppObjectSingletonEntity\";\r\nexport * from \"./AppObjectSingletonEntityRepo\";\r\nexport * from \"./AppObjectSingletonPM\";\r\nexport * from \"./AppObjectSingletonUC\";\r\nexport * from \"./getSingletonComponent\";\r\nexport * from \"./printAppObjectDetails\";\r\n"]}
@@ -65,4 +65,8 @@ export class DomainFactoryRepo extends AppObjectEntityRepo {
65
65
  }
66
66
  /** Unique type identifier for this component */
67
67
  DomainFactoryRepo.type = "DomainFactoryRepo";
68
+ export function makeDomainFactoryRepo(appObjects) {
69
+ const appObject = appObjects.getOrCreate("DomainFactoryRepo");
70
+ return new DomainFactoryRepo(appObject);
71
+ }
68
72
  //# sourceMappingURL=DomainFactoryRepo.js.map