@vived/core 1.5.0 → 1.6.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 (86) hide show
  1. package/README.md +1 -48
  2. package/dist/cjs/AppObject/AppObjectRepo.js +7 -0
  3. package/dist/cjs/AppObject/AppObjectRepo.js.map +1 -1
  4. package/dist/cjs/DomainFactories/Entities/DomainFactoryRepo.js +5 -0
  5. package/dist/cjs/DomainFactories/Entities/DomainFactoryRepo.js.map +1 -1
  6. package/dist/cjs/ExampleFeature/Factory/ExampleFeatureFactory.js +65 -0
  7. package/dist/cjs/ExampleFeature/Factory/ExampleFeatureFactory.js.map +1 -0
  8. package/dist/cjs/ValueObjects/Vector2.js +5 -6
  9. package/dist/cjs/ValueObjects/Vector2.js.map +1 -1
  10. package/dist/cjs/index.js +0 -1
  11. package/dist/cjs/index.js.map +1 -1
  12. package/dist/esm/AppObject/AppObjectRepo.js +7 -0
  13. package/dist/esm/AppObject/AppObjectRepo.js.map +1 -1
  14. package/dist/esm/DomainFactories/Entities/DomainFactoryRepo.js +4 -0
  15. package/dist/esm/DomainFactories/Entities/DomainFactoryRepo.js.map +1 -1
  16. package/dist/esm/ExampleFeature/Factory/ExampleFeatureFactory.js +60 -0
  17. package/dist/esm/ExampleFeature/Factory/ExampleFeatureFactory.js.map +1 -0
  18. package/dist/esm/ValueObjects/Vector2.js +5 -6
  19. package/dist/esm/ValueObjects/Vector2.js.map +1 -1
  20. package/dist/esm/index.js +0 -1
  21. package/dist/esm/index.js.map +1 -1
  22. package/dist/types/AppObject/AppObjectRepo.d.ts +7 -0
  23. package/dist/types/AppObject/AppObjectRepo.d.ts.map +1 -1
  24. package/dist/types/DomainFactories/Entities/DomainFactoryRepo.d.ts +1 -0
  25. package/dist/types/DomainFactories/Entities/DomainFactoryRepo.d.ts.map +1 -1
  26. package/dist/types/ExampleFeature/Factory/ExampleFeatureFactory.d.ts +44 -0
  27. package/dist/types/ExampleFeature/Factory/ExampleFeatureFactory.d.ts.map +1 -0
  28. package/dist/types/ValueObjects/Vector2.d.ts +2 -2
  29. package/dist/types/ValueObjects/Vector2.d.ts.map +1 -1
  30. package/dist/types/index.d.ts +0 -1
  31. package/dist/types/index.d.ts.map +1 -1
  32. package/package.json +1 -1
  33. package/dist/cjs/ExampleFeature/Adapters/index.js +0 -19
  34. package/dist/cjs/ExampleFeature/Adapters/index.js.map +0 -1
  35. package/dist/cjs/ExampleFeature/Controllers/index.js +0 -19
  36. package/dist/cjs/ExampleFeature/Controllers/index.js.map +0 -1
  37. package/dist/cjs/ExampleFeature/Entities/index.js +0 -20
  38. package/dist/cjs/ExampleFeature/Entities/index.js.map +0 -1
  39. package/dist/cjs/ExampleFeature/Factory/index.js +0 -18
  40. package/dist/cjs/ExampleFeature/Factory/index.js.map +0 -1
  41. package/dist/cjs/ExampleFeature/Factory/setupExampleFeature.js +0 -29
  42. package/dist/cjs/ExampleFeature/Factory/setupExampleFeature.js.map +0 -1
  43. package/dist/cjs/ExampleFeature/Mocks/index.js +0 -21
  44. package/dist/cjs/ExampleFeature/Mocks/index.js.map +0 -1
  45. package/dist/cjs/ExampleFeature/PMs/index.js +0 -19
  46. package/dist/cjs/ExampleFeature/PMs/index.js.map +0 -1
  47. package/dist/cjs/ExampleFeature/UCs/index.js +0 -19
  48. package/dist/cjs/ExampleFeature/UCs/index.js.map +0 -1
  49. package/dist/cjs/ExampleFeature/index.js +0 -24
  50. package/dist/cjs/ExampleFeature/index.js.map +0 -1
  51. package/dist/esm/ExampleFeature/Adapters/index.js +0 -3
  52. package/dist/esm/ExampleFeature/Adapters/index.js.map +0 -1
  53. package/dist/esm/ExampleFeature/Controllers/index.js +0 -3
  54. package/dist/esm/ExampleFeature/Controllers/index.js.map +0 -1
  55. package/dist/esm/ExampleFeature/Entities/index.js +0 -4
  56. package/dist/esm/ExampleFeature/Entities/index.js.map +0 -1
  57. package/dist/esm/ExampleFeature/Factory/index.js +0 -2
  58. package/dist/esm/ExampleFeature/Factory/index.js.map +0 -1
  59. package/dist/esm/ExampleFeature/Factory/setupExampleFeature.js +0 -26
  60. package/dist/esm/ExampleFeature/Factory/setupExampleFeature.js.map +0 -1
  61. package/dist/esm/ExampleFeature/Mocks/index.js +0 -5
  62. package/dist/esm/ExampleFeature/Mocks/index.js.map +0 -1
  63. package/dist/esm/ExampleFeature/PMs/index.js +0 -3
  64. package/dist/esm/ExampleFeature/PMs/index.js.map +0 -1
  65. package/dist/esm/ExampleFeature/UCs/index.js +0 -3
  66. package/dist/esm/ExampleFeature/UCs/index.js.map +0 -1
  67. package/dist/esm/ExampleFeature/index.js +0 -8
  68. package/dist/esm/ExampleFeature/index.js.map +0 -1
  69. package/dist/types/ExampleFeature/Adapters/index.d.ts +0 -3
  70. package/dist/types/ExampleFeature/Adapters/index.d.ts.map +0 -1
  71. package/dist/types/ExampleFeature/Controllers/index.d.ts +0 -3
  72. package/dist/types/ExampleFeature/Controllers/index.d.ts.map +0 -1
  73. package/dist/types/ExampleFeature/Entities/index.d.ts +0 -4
  74. package/dist/types/ExampleFeature/Entities/index.d.ts.map +0 -1
  75. package/dist/types/ExampleFeature/Factory/index.d.ts +0 -2
  76. package/dist/types/ExampleFeature/Factory/index.d.ts.map +0 -1
  77. package/dist/types/ExampleFeature/Factory/setupExampleFeature.d.ts +0 -17
  78. package/dist/types/ExampleFeature/Factory/setupExampleFeature.d.ts.map +0 -1
  79. package/dist/types/ExampleFeature/Mocks/index.d.ts +0 -5
  80. package/dist/types/ExampleFeature/Mocks/index.d.ts.map +0 -1
  81. package/dist/types/ExampleFeature/PMs/index.d.ts +0 -3
  82. package/dist/types/ExampleFeature/PMs/index.d.ts.map +0 -1
  83. package/dist/types/ExampleFeature/UCs/index.d.ts +0 -3
  84. package/dist/types/ExampleFeature/UCs/index.d.ts.map +0 -1
  85. package/dist/types/ExampleFeature/index.d.ts +0 -8
  86. package/dist/types/ExampleFeature/index.d.ts.map +0 -1
package/README.md CHANGED
@@ -66,54 +66,7 @@ The package includes a fully implemented `ExampleFeature` that demonstrates the
66
66
  - **Controllers/** - Simplified API for UI interaction
67
67
  - **Adapters/** - Connect UI frameworks to PMs
68
68
  - **Mocks/** - Test doubles for unit testing
69
-
70
- ### Implementation Patterns
71
- The example demonstrates:
72
- - Observable entities with memoized properties
73
- - Presentation managers with view model transformation
74
- - Use cases that implement business logic
75
- - Controllers that provide a simple UI-friendly API
76
- - Component registration and retrieval
77
- - Singleton component access
78
- - Test patterns for each component type
79
-
80
- ### Sample Usage
81
-
82
- ```typescript
83
- // Create a repository and an app object
84
- const repo = makeAppObjectRepo();
85
- const appObject = repo.getOrCreate("myObject");
86
-
87
- // Add an entity component to hold state
88
- class MyEntity extends AppObjectEntity {
89
- private _value = 0;
90
-
91
- get value() { return this._value; }
92
- set value(newValue: number) {
93
- this._value = newValue;
94
- this.notifyOnChange();
95
- }
96
- }
97
-
98
- // Add the entity to the app object
99
- const entity = new MyEntity(appObject, "MyEntity");
100
-
101
- // Create a presentation manager
102
- class MyPM extends AppObjectPM<{value: number}> {
103
- vmsAreEqual(a: {value: number}, b: {value: number}): boolean {
104
- return a.value === b.value;
105
- }
106
-
107
- updateViewModel() {
108
- const entity = this.getCachedLocalComponent<MyEntity>("MyEntity");
109
- if (entity) {
110
- this.doUpdateView({value: entity.value});
111
- }
112
- }
113
- }
114
-
115
- // The architecture enables clean, testable, and maintainable code
116
- ```
69
+ - **Factory/** - Factories for creating the features at runtime
117
70
 
118
71
  Refer to the `ExampleFeature` directory for a complete implementation example that shows the interaction between all component types.
119
72
 
@@ -131,6 +131,13 @@ class AppObjectRepoImp extends AppObjectRepo {
131
131
  }
132
132
  this.singletons.set(component.type, component);
133
133
  }
134
+ hasSingleton(type) {
135
+ if (this.singletons.has(type)) {
136
+ return true;
137
+ }
138
+ const components = this.getAllComponents(type);
139
+ return components.length === 1;
140
+ }
134
141
  getSingleton(type) {
135
142
  if (this.singletons.has(type)) {
136
143
  return this.singletons.get(type);
@@ -1 +1 @@
1
- {"version":3,"file":"AppObjectRepo.js","sourceRoot":"","sources":["../../../src/AppObject/AppObjectRepo.ts"],"names":[],"mappings":";;;AAqLA,8CAEC;AAvLD,0CAA6D;AAC7D,2CAAuD;AAGvD;;;;;;;;GAQG;AACH,MAAsB,aAAc,SAAQ,2BAAgB;CAiK3D;AAjKD,sCAiKC;AAED;;;;GAIG;AACH,SAAgB,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,uBAAY,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,uBAAY,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,IAAA,yBAAa,EAAC,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 * 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. Relpacing`\r\n );\r\n }\r\n\r\n this.singletons.set(component.type, component);\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"]}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DomainFactoryRepo = void 0;
4
+ exports.makeDomainFactoryRepo = makeDomainFactoryRepo;
4
5
  const AppObject_1 = require("../../AppObject");
5
6
  /**
6
7
  * Repository for managing DomainFactory instances in the application.
@@ -69,4 +70,8 @@ class DomainFactoryRepo extends AppObject_1.AppObjectEntityRepo {
69
70
  exports.DomainFactoryRepo = DomainFactoryRepo;
70
71
  /** Unique type identifier for this component */
71
72
  DomainFactoryRepo.type = "DomainFactoryRepo";
73
+ function makeDomainFactoryRepo(appObjects) {
74
+ const appObject = appObjects.getOrCreate("DomainFactoryRepo");
75
+ return new DomainFactoryRepo(appObject);
76
+ }
72
77
  //# sourceMappingURL=DomainFactoryRepo.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DomainFactoryRepo.js","sourceRoot":"","sources":["../../../../src/DomainFactories/Entities/DomainFactoryRepo.ts"],"names":[],"mappings":";;;AAAA,+CAKyB;AAGzB;;;;;;;;;;;;;GAaG;AACH,MAAa,iBAAkB,SAAQ,+BAAkC;IAIvE;;;;OAIG;IACH,MAAM,CAAC,GAAG,CAAC,UAAyB;QAClC,OAAO,IAAA,iCAAqB,EAC1B,iBAAiB,CAAC,IAAI,EACtB,UAAU,CACX,CAAC;IACJ,CAAC;IA+BD;;;;OAIG;IACH,SAAS,CAAC,IAAY;QACpB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACnC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC;IACtE,CAAC;IAED;;;OAGG;IACH,YAAY,SAAoB;QAC9B,KAAK,CAAC,SAAS,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;QA5C3C;;;;WAIG;QACH,gBAAW,GAAG,GAAG,EAAE;YACjB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAEnC,qCAAqC;YACrC,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,aAAa,EAAE,CAAC;YAChC,CAAC,CAAC,CAAC;YAEH,qCAAqC;YACrC,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC;YAEH,4CAA4C;YAC5C,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC;YAEH,0CAA0C;YAC1C,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,UAAU,EAAE,CAAC;YAC7B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IAkBF,CAAC;;AA7DH,8CA8DC;AA7DC,gDAAgD;AACzC,sBAAI,GAAG,mBAAmB,AAAtB,CAAuB","sourcesContent":["import {\r\n AppObject,\r\n AppObjectEntityRepo,\r\n AppObjectRepo,\r\n getSingletonComponent,\r\n} from \"../../AppObject\";\r\nimport { DomainFactory } from \"./DomainFactory\";\r\n\r\n/**\r\n * Repository for managing DomainFactory instances in the application.\r\n *\r\n * DomainFactoryRepo is implemented as a singleton that coordinates the setup\r\n * and initialization of all domain factories. It ensures that the setup phases\r\n * are executed in the correct order across all registered factories:\r\n * 1. All factories set up their entities first\r\n * 2. Then all factories set up their use cases\r\n * 3. Next all factories set up their presentation managers\r\n * 4. Finally, all factories perform their final setup operations\r\n *\r\n * This phased approach ensures that components in one domain can depend on\r\n * components from another domain being properly initialized.\r\n */\r\nexport class DomainFactoryRepo extends AppObjectEntityRepo<DomainFactory> {\r\n /** Unique type identifier for this component */\r\n static type = \"DomainFactoryRepo\";\r\n\r\n /**\r\n * Global accessor for the singleton repository\r\n * @param appObjects The AppObjectRepo to search in\r\n * @returns The singleton DomainFactoryRepo or undefined if not created yet\r\n */\r\n static get(appObjects: AppObjectRepo) {\r\n return getSingletonComponent<DomainFactoryRepo>(\r\n DomainFactoryRepo.type,\r\n appObjects\r\n );\r\n }\r\n\r\n /**\r\n * Orchestrates the setup of the entire domain layer in the correct sequence.\r\n * Calls each setup phase on all factories before proceeding to the next phase.\r\n * This ensures cross-domain dependencies are properly resolved.\r\n */\r\n setupDomain = () => {\r\n const allFactories = this.getAll();\r\n\r\n // Phase 1: Set up all entities first\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.setupEntities();\r\n });\r\n\r\n // Phase 2: Set up all use cases next\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.setupUCs();\r\n });\r\n\r\n // Phase 3: Set up all presentation managers\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.setupPMs();\r\n });\r\n\r\n // Phase 4: Perform final setup operations\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.finalSetup();\r\n });\r\n };\r\n\r\n /**\r\n * Retrieves a domain factory by its name.\r\n * @param name The name of the domain factory to find\r\n * @returns The matching domain factory or undefined if not found\r\n */\r\n getByName(name: string): DomainFactory | undefined {\r\n const allFactories = this.getAll();\r\n return allFactories.find((factory) => factory.factoryName === name);\r\n }\r\n\r\n /**\r\n * Creates a new DomainFactoryRepo and registers it with the given AppObject.\r\n * @param appObject The parent AppObject this component will be attached to\r\n */\r\n constructor(appObject: AppObject) {\r\n super(appObject, DomainFactoryRepo.type);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"DomainFactoryRepo.js","sourceRoot":"","sources":["../../../../src/DomainFactories/Entities/DomainFactoryRepo.ts"],"names":[],"mappings":";;;AAsFA,sDAGC;AAzFD,+CAKyB;AAGzB;;;;;;;;;;;;;GAaG;AACH,MAAa,iBAAkB,SAAQ,+BAAkC;IAIvE;;;;OAIG;IACH,MAAM,CAAC,GAAG,CAAC,UAAyB;QAClC,OAAO,IAAA,iCAAqB,EAC1B,iBAAiB,CAAC,IAAI,EACtB,UAAU,CACX,CAAC;IACJ,CAAC;IA+BD;;;;OAIG;IACH,SAAS,CAAC,IAAY;QACpB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACnC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC;IACtE,CAAC;IAED;;;OAGG;IACH,YAAY,SAAoB;QAC9B,KAAK,CAAC,SAAS,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;QA5C3C;;;;WAIG;QACH,gBAAW,GAAG,GAAG,EAAE;YACjB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAEnC,qCAAqC;YACrC,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,aAAa,EAAE,CAAC;YAChC,CAAC,CAAC,CAAC;YAEH,qCAAqC;YACrC,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC;YAEH,4CAA4C;YAC5C,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC;YAEH,0CAA0C;YAC1C,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,UAAU,EAAE,CAAC;YAC7B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IAkBF,CAAC;;AA7DH,8CA8DC;AA7DC,gDAAgD;AACzC,sBAAI,GAAG,mBAAmB,AAAtB,CAAuB;AA8DpC,SAAgB,qBAAqB,CAAC,UAAyB;IAC7D,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC;IAC9D,OAAO,IAAI,iBAAiB,CAAC,SAAS,CAAC,CAAC;AAC1C,CAAC","sourcesContent":["import {\r\n AppObject,\r\n AppObjectEntityRepo,\r\n AppObjectRepo,\r\n getSingletonComponent,\r\n} from \"../../AppObject\";\r\nimport { DomainFactory } from \"./DomainFactory\";\r\n\r\n/**\r\n * Repository for managing DomainFactory instances in the application.\r\n *\r\n * DomainFactoryRepo is implemented as a singleton that coordinates the setup\r\n * and initialization of all domain factories. It ensures that the setup phases\r\n * are executed in the correct order across all registered factories:\r\n * 1. All factories set up their entities first\r\n * 2. Then all factories set up their use cases\r\n * 3. Next all factories set up their presentation managers\r\n * 4. Finally, all factories perform their final setup operations\r\n *\r\n * This phased approach ensures that components in one domain can depend on\r\n * components from another domain being properly initialized.\r\n */\r\nexport class DomainFactoryRepo extends AppObjectEntityRepo<DomainFactory> {\r\n /** Unique type identifier for this component */\r\n static type = \"DomainFactoryRepo\";\r\n\r\n /**\r\n * Global accessor for the singleton repository\r\n * @param appObjects The AppObjectRepo to search in\r\n * @returns The singleton DomainFactoryRepo or undefined if not created yet\r\n */\r\n static get(appObjects: AppObjectRepo) {\r\n return getSingletonComponent<DomainFactoryRepo>(\r\n DomainFactoryRepo.type,\r\n appObjects\r\n );\r\n }\r\n\r\n /**\r\n * Orchestrates the setup of the entire domain layer in the correct sequence.\r\n * Calls each setup phase on all factories before proceeding to the next phase.\r\n * This ensures cross-domain dependencies are properly resolved.\r\n */\r\n setupDomain = () => {\r\n const allFactories = this.getAll();\r\n\r\n // Phase 1: Set up all entities first\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.setupEntities();\r\n });\r\n\r\n // Phase 2: Set up all use cases next\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.setupUCs();\r\n });\r\n\r\n // Phase 3: Set up all presentation managers\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.setupPMs();\r\n });\r\n\r\n // Phase 4: Perform final setup operations\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.finalSetup();\r\n });\r\n };\r\n\r\n /**\r\n * Retrieves a domain factory by its name.\r\n * @param name The name of the domain factory to find\r\n * @returns The matching domain factory or undefined if not found\r\n */\r\n getByName(name: string): DomainFactory | undefined {\r\n const allFactories = this.getAll();\r\n return allFactories.find((factory) => factory.factoryName === name);\r\n }\r\n\r\n /**\r\n * Creates a new DomainFactoryRepo and registers it with the given AppObject.\r\n * @param appObject The parent AppObject this component will be attached to\r\n */\r\n constructor(appObject: AppObject) {\r\n super(appObject, DomainFactoryRepo.type);\r\n }\r\n}\r\n\r\nexport function makeDomainFactoryRepo(appObjects: AppObjectRepo) {\r\n const appObject = appObjects.getOrCreate(\"DomainFactoryRepo\");\r\n return new DomainFactoryRepo(appObject);\r\n}"]}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExampleFeatureFactory = void 0;
4
+ exports.makeExampleFeatureFactory = makeExampleFeatureFactory;
5
+ const DomainFactories_1 = require("../../DomainFactories");
6
+ const ExampleSingletonEntity_1 = require("../Entities/ExampleSingletonEntity");
7
+ const ExampleSingletonPM_1 = require("../PMs/ExampleSingletonPM");
8
+ const ToggleExampleBooleanUC_1 = require("../UCs/ToggleExampleBooleanUC");
9
+ /**
10
+ * Factory responsible for setting up the Example Feature domain components.
11
+ *
12
+ * This factory initializes all entities, use cases, and presentation models
13
+ * required for the Example Feature functionality. It follows the domain-driven
14
+ * design pattern by organizing components into their respective layers.
15
+ *
16
+ * @extends DomainFactory
17
+ */
18
+ class ExampleFeatureFactory extends DomainFactories_1.DomainFactory {
19
+ constructor() {
20
+ super(...arguments);
21
+ this.factoryName = "ExampleFeatureFactory";
22
+ }
23
+ /**
24
+ * Sets up all entities required for the Example Feature.
25
+ *
26
+ * Initializes singleton entities that maintain the state and business
27
+ * logic for the example feature functionality.
28
+ */
29
+ setupEntities() {
30
+ (0, ExampleSingletonEntity_1.makeSingletonEntityExample)(this.appObject);
31
+ }
32
+ /**
33
+ * Sets up all use cases for the Example Feature.
34
+ *
35
+ * Initializes use cases that define the business operations and
36
+ * workflows available in the example feature.
37
+ */
38
+ setupUCs() {
39
+ (0, ToggleExampleBooleanUC_1.makeToggleExampleBooleanUC)(this.appObject);
40
+ }
41
+ /**
42
+ * Sets up all presentation models for the Example Feature.
43
+ *
44
+ * Initializes presentation models that handle the view logic and
45
+ * state management for UI components related to the example feature.
46
+ */
47
+ setupPMs() {
48
+ (0, ExampleSingletonPM_1.makeExampleSingletonPM)(this.appObject);
49
+ }
50
+ /**
51
+ * Performs any final setup operations after all components are initialized.
52
+ *
53
+ * This method is called after entities, use cases, and presentation models
54
+ * have been set up. Currently no additional setup is required for this feature.
55
+ */
56
+ finalSetup() {
57
+ // No additional setup required for this feature
58
+ }
59
+ }
60
+ exports.ExampleFeatureFactory = ExampleFeatureFactory;
61
+ function makeExampleFeatureFactory(appObjects) {
62
+ const appObject = appObjects.getOrCreate("ExampleFeatureFactory");
63
+ return new ExampleFeatureFactory(appObject);
64
+ }
65
+ //# sourceMappingURL=ExampleFeatureFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExampleFeatureFactory.js","sourceRoot":"","sources":["../../../../src/ExampleFeature/Factory/ExampleFeatureFactory.ts"],"names":[],"mappings":";;;AAgEA,8DAGC;AAlED,2DAAsD;AACtD,+EAAgF;AAChF,kEAAmE;AACnE,0EAA2E;AAE3E;;;;;;;;GAQG;AACH,MAAa,qBAAsB,SAAQ,+BAAa;IAAxD;;QAEC,gBAAW,GAAG,uBAAuB,CAAC;IA6CvC,CAAC;IA3CA;;;;;OAKG;IACH,aAAa;QAEZ,IAAA,mDAA0B,EAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;OAKG;IACH,QAAQ;QAEP,IAAA,mDAA0B,EAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;OAKG;IACH,QAAQ;QAEP,IAAA,2CAAsB,EAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAED;;;;;OAKG;IACH,UAAU;QAET,gDAAgD;IACjD,CAAC;CACD;AA/CD,sDA+CC;AAED,SAAgB,yBAAyB,CAAC,UAAyB;IAClE,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,uBAAuB,CAAC,CAAC;IAClE,OAAO,IAAI,qBAAqB,CAAC,SAAS,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["import { AppObjectRepo } from \"../../AppObject\";\r\nimport { DomainFactory } from \"../../DomainFactories\";\r\nimport { makeSingletonEntityExample } from \"../Entities/ExampleSingletonEntity\";\r\nimport { makeExampleSingletonPM } from \"../PMs/ExampleSingletonPM\";\r\nimport { makeToggleExampleBooleanUC } from \"../UCs/ToggleExampleBooleanUC\";\r\n\r\n/**\r\n * Factory responsible for setting up the Example Feature domain components.\r\n * \r\n * This factory initializes all entities, use cases, and presentation models\r\n * required for the Example Feature functionality. It follows the domain-driven\r\n * design pattern by organizing components into their respective layers.\r\n * \r\n * @extends DomainFactory\r\n */\r\nexport class ExampleFeatureFactory extends DomainFactory\r\n{\r\n\tfactoryName = \"ExampleFeatureFactory\";\r\n\r\n\t/**\r\n\t * Sets up all entities required for the Example Feature.\r\n\t * \r\n\t * Initializes singleton entities that maintain the state and business\r\n\t * logic for the example feature functionality.\r\n\t */\r\n\tsetupEntities(): void\r\n\t{\r\n\t\tmakeSingletonEntityExample(this.appObject);\r\n\t}\r\n\r\n\t/**\r\n\t * Sets up all use cases for the Example Feature.\r\n\t * \r\n\t * Initializes use cases that define the business operations and\r\n\t * workflows available in the example feature.\r\n\t */\r\n\tsetupUCs(): void\r\n\t{\r\n\t\tmakeToggleExampleBooleanUC(this.appObject);\r\n\t}\r\n\r\n\t/**\r\n\t * Sets up all presentation models for the Example Feature.\r\n\t * \r\n\t * Initializes presentation models that handle the view logic and\r\n\t * state management for UI components related to the example feature.\r\n\t */\r\n\tsetupPMs(): void\r\n\t{\r\n\t\tmakeExampleSingletonPM(this.appObject);\r\n\t}\r\n\r\n\t/**\r\n\t * Performs any final setup operations after all components are initialized.\r\n\t * \r\n\t * This method is called after entities, use cases, and presentation models\r\n\t * have been set up. Currently no additional setup is required for this feature.\r\n\t */\r\n\tfinalSetup(): void\r\n\t{\r\n\t\t// No additional setup required for this feature\r\n\t}\r\n}\r\n\r\nexport function makeExampleFeatureFactory(appObjects: AppObjectRepo):ExampleFeatureFactory {\r\n\tconst appObject = appObjects.getOrCreate(\"ExampleFeatureFactory\");\r\n\treturn new ExampleFeatureFactory(appObject);\r\n}"]}
@@ -168,16 +168,15 @@ Vector2.Dot = (a, b) => {
168
168
  return a.x * b.x + a.y * b.y;
169
169
  };
170
170
  /**
171
- * Calculates the dot product between Vectors A and B
171
+ * Calculates the angle between Vectors A and B
172
172
  * @param a Vector A
173
173
  * @param b Vector B
174
- * @returns A . B
174
+ * @returns The angle between A and B
175
175
  */
176
176
  Vector2.AngleBetween = (a, b) => {
177
- const dot = Vector2.Dot(a, b);
178
- const magnitudes = a.magnitude * b.magnitude;
179
- const angRadians = Math.acos(dot / magnitudes);
180
- return _1.Angle.FromRadians(angRadians);
177
+ const angleA = Math.atan2(a.y, a.x);
178
+ const angleB = Math.atan2(b.y, b.x);
179
+ return _1.Angle.FromRadians(angleB - angleA);
181
180
  };
182
181
  /**
183
182
  * Calculates the Cross product between Vectors A and B
@@ -1 +1 @@
1
- {"version":3,"file":"Vector2.js","sourceRoot":"","sources":["../../../src/ValueObjects/Vector2.ts"],"names":[],"mappings":"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","sourcesContent":["import { Angle } from \".\";\r\n\r\nexport class Vector2 {\r\n /**\r\n * Creates a zero vector\r\n * @returns Vector [0,0]\r\n */\r\n public static Zero(): Vector2 {\r\n return new Vector2(0, 0);\r\n }\r\n\r\n /**\r\n * Creates a one vector\r\n * @returns Vector [1,1]\r\n */\r\n public static One(): Vector2 {\r\n return new Vector2(1, 1);\r\n }\r\n\r\n /**\r\n * Checks to see if Vector A equals Vector B\r\n * @param a Vector A\r\n * @param b Vector B\r\n * @returns True if Vector A === Vector B\r\n */\r\n public static Equal(a: Vector2, b: Vector2): boolean {\r\n if (a.x !== b.x) return false;\r\n if (a.y !== b.y) return false;\r\n return true;\r\n }\r\n\r\n /**\r\n * Creates a Vector from a Data Transfer Object\r\n * @param dto The Data Transfer Object\r\n * @returns The Vector\r\n */\r\n public static FromDTO(dto: { x: number; y: number }): Vector2 {\r\n return new Vector2(dto.x, dto.y);\r\n }\r\n\r\n /**\r\n * Adds Vector B to Vector A\r\n * @param a Vector A\r\n * @param b Vector B\r\n * @returns A + B\r\n */\r\n public static Add(a: Vector2, b: Vector2): Vector2 {\r\n return new Vector2(a.x + b.x, a.y + b.y);\r\n }\r\n\r\n /**\r\n * Subtracts Vector B from Vector A\r\n * @param a Vector A\r\n * @param b Vector B\r\n * @returns A - B\r\n */\r\n public static Subtract(a: Vector2, b: Vector2): Vector2 {\r\n return new Vector2(a.x - b.x, a.y - b.y);\r\n }\r\n\r\n /**\r\n * Checks to see if Vector A is close to Vector B\r\n * @param a Vector A\r\n * @param b Vector B\r\n * @param threshold Tolerance to define \"close\". Defaults to 0.01\r\n * @returns True if A and B are close enough\r\n */\r\n public static Close = (\r\n a: Vector2,\r\n b: Vector2,\r\n threshold: number = 0.01\r\n ): boolean => {\r\n const diff = Vector2.Subtract(a, b);\r\n const diffMag = diff.magnitude;\r\n\r\n if (diffMag < threshold) return true;\r\n else return false;\r\n };\r\n\r\n /**\r\n * Rotates a vector by an angle\r\n * @param vec The original vector\r\n * @param angle The angle\r\n * @returns A new Vector that has been rotated from the original by an angle\r\n */\r\n public static Rotate = (vec: Vector2, angle: Angle): Vector2 => {\r\n const x = vec.x * Math.cos(angle.radians) - vec.y * Math.sin(angle.radians);\r\n const y = vec.x * Math.sin(angle.radians) + vec.y * Math.cos(angle.radians);\r\n return new Vector2(x, y);\r\n };\r\n\r\n /**\r\n * Scales a vector uniformly\r\n * @param vector The original vector\r\n * @param scale Scale factor\r\n * @returns A new, scaled vector\r\n */\r\n public static Scale = (vector: Vector2, scale: number): Vector2 => {\r\n const x = scale * vector.x;\r\n const y = scale * vector.y;\r\n return new Vector2(x, y);\r\n };\r\n\r\n /**\r\n * Creates a new vector of a given length and a unit that is equal to the original vector\r\n * @param vector The original vector. This determines the unit of the final vector\r\n * @param length The desired length of the final vector\r\n * @returns The final vector\r\n */\r\n public static NewVectorOfLength = (\r\n vector: Vector2,\r\n length: number\r\n ): Vector2 => {\r\n const unit = vector.unit;\r\n const x = length * unit.x;\r\n const y = length * unit.y;\r\n return new Vector2(x, y);\r\n };\r\n\r\n /**\r\n * Calculate the dot product between Vectors A and B\r\n * @param a Vector A\r\n * @param b Vector B\r\n * @returns The Dot product between A and B\r\n */\r\n public static Dot = (a: Vector2, b: Vector2): number => {\r\n return a.x * b.x + a.y * b.y;\r\n };\r\n\r\n /**\r\n * Calculates the dot product between Vectors A and B\r\n * @param a Vector A\r\n * @param b Vector B\r\n * @returns A . B\r\n */\r\n public static AngleBetween = (a: Vector2, b: Vector2): Angle => {\r\n const dot = Vector2.Dot(a, b);\r\n const magnitudes = a.magnitude * b.magnitude;\r\n\r\n const angRadians = Math.acos(dot / magnitudes);\r\n\r\n return Angle.FromRadians(angRadians);\r\n };\r\n\r\n /**\r\n * Calculates the Cross product between Vectors A and B\r\n * @param a Vector A\r\n * @param b Vector B\r\n * @returns A X B\r\n */\r\n public static Cross = (a: Vector2, b: Vector2): number => {\r\n return a.x * b.y - a.y * b.x;\r\n };\r\n\r\n readonly x: number;\r\n readonly y: number;\r\n\r\n /**\r\n * Get the magnitude (length) of the vector\r\n */\r\n get magnitude(): number {\r\n const xSqr = this.x * this.x;\r\n const ySqr = this.y * this.y;\r\n\r\n const magnitude = Math.sqrt(xSqr + ySqr);\r\n return magnitude;\r\n }\r\n \r\n /**\r\n * @deprecated Use magnitude instead - this property is kept for backward compatibility\r\n * Get the magnitude (length) of the vector\r\n */\r\n get magnitued(): number {\r\n return this.magnitude;\r\n }\r\n\r\n /**\r\n * Get the unit vector\r\n */\r\n get unit(): Vector2 {\r\n const mag = this.magnitude;\r\n if (mag === 0) {\r\n return Vector2.Zero();\r\n }\r\n\r\n const unitX = this.x / mag;\r\n const unitY = this.y / mag;\r\n return new Vector2(unitX, unitY);\r\n }\r\n\r\n /**\r\n * Returns the angle of the direction of this vector in degrees.\r\n * A right vector [1,0] will return 0, a left vector [-1,0] will return 180, an up vector [0,1] will return 90 and a down vector [0,-1] will return -90\r\n */\r\n get theta(): number {\r\n return (Math.atan2(this.y, this.x) * 180) / Math.PI;\r\n }\r\n\r\n /**\r\n * Returns the vector as an array of numbers [x,y]\r\n */\r\n get array(): [number, number] {\r\n return [this.x, this.y];\r\n }\r\n\r\n /**\r\n * Get the vector as a Data Transfer Object\r\n */\r\n get dto(): { x: number; y: number } {\r\n return { x: this.x, y: this.y };\r\n }\r\n\r\n constructor(x: number, y: number) {\r\n this.x = x;\r\n this.y = y;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"Vector2.js","sourceRoot":"","sources":["../../../src/ValueObjects/Vector2.ts"],"names":[],"mappings":"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","sourcesContent":["import { Angle } from \".\";\r\n\r\nexport class Vector2 {\r\n /**\r\n * Creates a zero vector\r\n * @returns Vector [0,0]\r\n */\r\n public static Zero(): Vector2 {\r\n return new Vector2(0, 0);\r\n }\r\n\r\n /**\r\n * Creates a one vector\r\n * @returns Vector [1,1]\r\n */\r\n public static One(): Vector2 {\r\n return new Vector2(1, 1);\r\n }\r\n\r\n /**\r\n * Checks to see if Vector A equals Vector B\r\n * @param a Vector A\r\n * @param b Vector B\r\n * @returns True if Vector A === Vector B\r\n */\r\n public static Equal(a: Vector2, b: Vector2): boolean {\r\n if (a.x !== b.x) return false;\r\n if (a.y !== b.y) return false;\r\n return true;\r\n }\r\n\r\n /**\r\n * Creates a Vector from a Data Transfer Object\r\n * @param dto The Data Transfer Object\r\n * @returns The Vector\r\n */\r\n public static FromDTO(dto: { x: number; y: number }): Vector2 {\r\n return new Vector2(dto.x, dto.y);\r\n }\r\n\r\n /**\r\n * Adds Vector B to Vector A\r\n * @param a Vector A\r\n * @param b Vector B\r\n * @returns A + B\r\n */\r\n public static Add(a: Vector2, b: Vector2): Vector2 {\r\n return new Vector2(a.x + b.x, a.y + b.y);\r\n }\r\n\r\n /**\r\n * Subtracts Vector B from Vector A\r\n * @param a Vector A\r\n * @param b Vector B\r\n * @returns A - B\r\n */\r\n public static Subtract(a: Vector2, b: Vector2): Vector2 {\r\n return new Vector2(a.x - b.x, a.y - b.y);\r\n }\r\n\r\n /**\r\n * Checks to see if Vector A is close to Vector B\r\n * @param a Vector A\r\n * @param b Vector B\r\n * @param threshold Tolerance to define \"close\". Defaults to 0.01\r\n * @returns True if A and B are close enough\r\n */\r\n public static Close = (\r\n a: Vector2,\r\n b: Vector2,\r\n threshold: number = 0.01\r\n ): boolean => {\r\n const diff = Vector2.Subtract(a, b);\r\n const diffMag = diff.magnitude;\r\n\r\n if (diffMag < threshold) return true;\r\n else return false;\r\n };\r\n\r\n /**\r\n * Rotates a vector by an angle\r\n * @param vec The original vector\r\n * @param angle The angle\r\n * @returns A new Vector that has been rotated from the original by an angle\r\n */\r\n public static Rotate = (vec: Vector2, angle: Angle): Vector2 => {\r\n const x = vec.x * Math.cos(angle.radians) - vec.y * Math.sin(angle.radians);\r\n const y = vec.x * Math.sin(angle.radians) + vec.y * Math.cos(angle.radians);\r\n return new Vector2(x, y);\r\n };\r\n\r\n /**\r\n * Scales a vector uniformly\r\n * @param vector The original vector\r\n * @param scale Scale factor\r\n * @returns A new, scaled vector\r\n */\r\n public static Scale = (vector: Vector2, scale: number): Vector2 => {\r\n const x = scale * vector.x;\r\n const y = scale * vector.y;\r\n return new Vector2(x, y);\r\n };\r\n\r\n /**\r\n * Creates a new vector of a given length and a unit that is equal to the original vector\r\n * @param vector The original vector. This determines the unit of the final vector\r\n * @param length The desired length of the final vector\r\n * @returns The final vector\r\n */\r\n public static NewVectorOfLength = (\r\n vector: Vector2,\r\n length: number\r\n ): Vector2 => {\r\n const unit = vector.unit;\r\n const x = length * unit.x;\r\n const y = length * unit.y;\r\n return new Vector2(x, y);\r\n };\r\n\r\n /**\r\n * Calculate the dot product between Vectors A and B\r\n * @param a Vector A\r\n * @param b Vector B\r\n * @returns The Dot product between A and B\r\n */\r\n public static Dot = (a: Vector2, b: Vector2): number => {\r\n return a.x * b.x + a.y * b.y;\r\n };\r\n /**\r\n * Calculates the angle between Vectors A and B\r\n * @param a Vector A\r\n * @param b Vector B\r\n * @returns The angle between A and B\r\n */\r\n public static AngleBetween = (a: Vector2, b: Vector2): Angle => {\r\n const angleA = Math.atan2(a.y, a.x);\r\n const angleB = Math.atan2(b.y, b.x);\r\n\r\n return Angle.FromRadians(angleB - angleA);\r\n };\r\n\r\n /**\r\n * Calculates the Cross product between Vectors A and B\r\n * @param a Vector A\r\n * @param b Vector B\r\n * @returns A X B\r\n */\r\n public static Cross = (a: Vector2, b: Vector2): number => {\r\n return a.x * b.y - a.y * b.x;\r\n };\r\n\r\n readonly x: number;\r\n readonly y: number;\r\n\r\n /**\r\n * Get the magnitude (length) of the vector\r\n */\r\n get magnitude(): number {\r\n const xSqr = this.x * this.x;\r\n const ySqr = this.y * this.y;\r\n\r\n const magnitude = Math.sqrt(xSqr + ySqr);\r\n return magnitude;\r\n }\r\n\r\n /**\r\n * @deprecated Use magnitude instead - this property is kept for backward compatibility\r\n * Get the magnitude (length) of the vector\r\n */\r\n get magnitued(): number {\r\n return this.magnitude;\r\n }\r\n\r\n /**\r\n * Get the unit vector\r\n */\r\n get unit(): Vector2 {\r\n const mag = this.magnitude;\r\n if (mag === 0) {\r\n return Vector2.Zero();\r\n }\r\n\r\n const unitX = this.x / mag;\r\n const unitY = this.y / mag;\r\n return new Vector2(unitX, unitY);\r\n }\r\n\r\n /**\r\n * Returns the angle of the direction of this vector in degrees.\r\n * A right vector [1,0] will return 0, a left vector [-1,0] will return 180, an up vector [0,1] will return 90 and a down vector [0,-1] will return -90\r\n */\r\n get theta(): number {\r\n return (Math.atan2(this.y, this.x) * 180) / Math.PI;\r\n }\r\n\r\n /**\r\n * Returns the vector as an array of numbers [x,y]\r\n */\r\n get array(): [number, number] {\r\n return [this.x, this.y];\r\n }\r\n\r\n /**\r\n * Get the vector as a Data Transfer Object\r\n */\r\n get dto(): { x: number; y: number } {\r\n return { x: this.x, y: this.y };\r\n }\r\n\r\n constructor(x: number, y: number) {\r\n this.x = x;\r\n this.y = y;\r\n }\r\n}\r\n"]}
package/dist/cjs/index.js CHANGED
@@ -17,7 +17,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./AppObject"), exports);
18
18
  __exportStar(require("./DomainFactories"), exports);
19
19
  __exportStar(require("./Entities"), exports);
20
- __exportStar(require("./ExampleFeature"), exports);
21
20
  __exportStar(require("./Types"), exports);
22
21
  __exportStar(require("./Utilities"), exports);
23
22
  __exportStar(require("./ValueObjects"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,oDAAiC;AACjC,6CAA2B;AAC3B,mDAAgC;AAChC,0CAAwB;AACxB,8CAA4B;AAC5B,iDAA+B","sourcesContent":["export * from \"./AppObject\";\r\nexport * from \"./DomainFactories\"\r\nexport * from \"./Entities\";\r\nexport * from \"./ExampleFeature\"\r\nexport * from \"./Types\";\r\nexport * from \"./Utilities\";\r\nexport * from \"./ValueObjects\";\r\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,oDAAiC;AACjC,6CAA2B;AAC3B,0CAAwB;AACxB,8CAA4B;AAC5B,iDAA+B","sourcesContent":["export * from \"./AppObject\";\r\nexport * from \"./DomainFactories\"\r\nexport * from \"./Entities\";\r\nexport * from \"./Types\";\r\nexport * from \"./Utilities\";\r\nexport * from \"./ValueObjects\";\r\n"]}
@@ -126,6 +126,13 @@ class AppObjectRepoImp extends AppObjectRepo {
126
126
  }
127
127
  this.singletons.set(component.type, component);
128
128
  }
129
+ hasSingleton(type) {
130
+ if (this.singletons.has(type)) {
131
+ return true;
132
+ }
133
+ const components = this.getAllComponents(type);
134
+ return components.length === 1;
135
+ }
129
136
  getSingleton(type) {
130
137
  if (this.singletons.has(type)) {
131
138
  return this.singletons.get(type);
@@ -1 +1 @@
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 * 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 * 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. Relpacing`\r\n );\r\n }\r\n\r\n this.singletons.set(component.type, component);\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"]}
@@ -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
@@ -1 +1 @@
1
- {"version":3,"file":"DomainFactoryRepo.js","sourceRoot":"","sources":["../../../../src/DomainFactories/Entities/DomainFactoryRepo.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,mBAAmB,EAEnB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAGzB;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,iBAAkB,SAAQ,mBAAkC;IAIvE;;;;OAIG;IACH,MAAM,CAAC,GAAG,CAAC,UAAyB;QAClC,OAAO,qBAAqB,CAC1B,iBAAiB,CAAC,IAAI,EACtB,UAAU,CACX,CAAC;IACJ,CAAC;IA+BD;;;;OAIG;IACH,SAAS,CAAC,IAAY;QACpB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACnC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC;IACtE,CAAC;IAED;;;OAGG;IACH,YAAY,SAAoB;QAC9B,KAAK,CAAC,SAAS,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;QA5C3C;;;;WAIG;QACH,gBAAW,GAAG,GAAG,EAAE;YACjB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAEnC,qCAAqC;YACrC,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,aAAa,EAAE,CAAC;YAChC,CAAC,CAAC,CAAC;YAEH,qCAAqC;YACrC,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC;YAEH,4CAA4C;YAC5C,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC;YAEH,0CAA0C;YAC1C,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,UAAU,EAAE,CAAC;YAC7B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IAkBF,CAAC;;AA5DD,gDAAgD;AACzC,sBAAI,GAAG,mBAAmB,AAAtB,CAAuB","sourcesContent":["import {\r\n AppObject,\r\n AppObjectEntityRepo,\r\n AppObjectRepo,\r\n getSingletonComponent,\r\n} from \"../../AppObject\";\r\nimport { DomainFactory } from \"./DomainFactory\";\r\n\r\n/**\r\n * Repository for managing DomainFactory instances in the application.\r\n *\r\n * DomainFactoryRepo is implemented as a singleton that coordinates the setup\r\n * and initialization of all domain factories. It ensures that the setup phases\r\n * are executed in the correct order across all registered factories:\r\n * 1. All factories set up their entities first\r\n * 2. Then all factories set up their use cases\r\n * 3. Next all factories set up their presentation managers\r\n * 4. Finally, all factories perform their final setup operations\r\n *\r\n * This phased approach ensures that components in one domain can depend on\r\n * components from another domain being properly initialized.\r\n */\r\nexport class DomainFactoryRepo extends AppObjectEntityRepo<DomainFactory> {\r\n /** Unique type identifier for this component */\r\n static type = \"DomainFactoryRepo\";\r\n\r\n /**\r\n * Global accessor for the singleton repository\r\n * @param appObjects The AppObjectRepo to search in\r\n * @returns The singleton DomainFactoryRepo or undefined if not created yet\r\n */\r\n static get(appObjects: AppObjectRepo) {\r\n return getSingletonComponent<DomainFactoryRepo>(\r\n DomainFactoryRepo.type,\r\n appObjects\r\n );\r\n }\r\n\r\n /**\r\n * Orchestrates the setup of the entire domain layer in the correct sequence.\r\n * Calls each setup phase on all factories before proceeding to the next phase.\r\n * This ensures cross-domain dependencies are properly resolved.\r\n */\r\n setupDomain = () => {\r\n const allFactories = this.getAll();\r\n\r\n // Phase 1: Set up all entities first\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.setupEntities();\r\n });\r\n\r\n // Phase 2: Set up all use cases next\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.setupUCs();\r\n });\r\n\r\n // Phase 3: Set up all presentation managers\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.setupPMs();\r\n });\r\n\r\n // Phase 4: Perform final setup operations\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.finalSetup();\r\n });\r\n };\r\n\r\n /**\r\n * Retrieves a domain factory by its name.\r\n * @param name The name of the domain factory to find\r\n * @returns The matching domain factory or undefined if not found\r\n */\r\n getByName(name: string): DomainFactory | undefined {\r\n const allFactories = this.getAll();\r\n return allFactories.find((factory) => factory.factoryName === name);\r\n }\r\n\r\n /**\r\n * Creates a new DomainFactoryRepo and registers it with the given AppObject.\r\n * @param appObject The parent AppObject this component will be attached to\r\n */\r\n constructor(appObject: AppObject) {\r\n super(appObject, DomainFactoryRepo.type);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"DomainFactoryRepo.js","sourceRoot":"","sources":["../../../../src/DomainFactories/Entities/DomainFactoryRepo.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,mBAAmB,EAEnB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAGzB;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,iBAAkB,SAAQ,mBAAkC;IAIvE;;;;OAIG;IACH,MAAM,CAAC,GAAG,CAAC,UAAyB;QAClC,OAAO,qBAAqB,CAC1B,iBAAiB,CAAC,IAAI,EACtB,UAAU,CACX,CAAC;IACJ,CAAC;IA+BD;;;;OAIG;IACH,SAAS,CAAC,IAAY;QACpB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACnC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC;IACtE,CAAC;IAED;;;OAGG;IACH,YAAY,SAAoB;QAC9B,KAAK,CAAC,SAAS,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;QA5C3C;;;;WAIG;QACH,gBAAW,GAAG,GAAG,EAAE;YACjB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAEnC,qCAAqC;YACrC,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,aAAa,EAAE,CAAC;YAChC,CAAC,CAAC,CAAC;YAEH,qCAAqC;YACrC,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC;YAEH,4CAA4C;YAC5C,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC;YAEH,0CAA0C;YAC1C,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrC,aAAa,CAAC,UAAU,EAAE,CAAC;YAC7B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IAkBF,CAAC;;AA5DD,gDAAgD;AACzC,sBAAI,GAAG,mBAAmB,AAAtB,CAAuB;AA8DpC,MAAM,UAAU,qBAAqB,CAAC,UAAyB;IAC7D,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC;IAC9D,OAAO,IAAI,iBAAiB,CAAC,SAAS,CAAC,CAAC;AAC1C,CAAC","sourcesContent":["import {\r\n AppObject,\r\n AppObjectEntityRepo,\r\n AppObjectRepo,\r\n getSingletonComponent,\r\n} from \"../../AppObject\";\r\nimport { DomainFactory } from \"./DomainFactory\";\r\n\r\n/**\r\n * Repository for managing DomainFactory instances in the application.\r\n *\r\n * DomainFactoryRepo is implemented as a singleton that coordinates the setup\r\n * and initialization of all domain factories. It ensures that the setup phases\r\n * are executed in the correct order across all registered factories:\r\n * 1. All factories set up their entities first\r\n * 2. Then all factories set up their use cases\r\n * 3. Next all factories set up their presentation managers\r\n * 4. Finally, all factories perform their final setup operations\r\n *\r\n * This phased approach ensures that components in one domain can depend on\r\n * components from another domain being properly initialized.\r\n */\r\nexport class DomainFactoryRepo extends AppObjectEntityRepo<DomainFactory> {\r\n /** Unique type identifier for this component */\r\n static type = \"DomainFactoryRepo\";\r\n\r\n /**\r\n * Global accessor for the singleton repository\r\n * @param appObjects The AppObjectRepo to search in\r\n * @returns The singleton DomainFactoryRepo or undefined if not created yet\r\n */\r\n static get(appObjects: AppObjectRepo) {\r\n return getSingletonComponent<DomainFactoryRepo>(\r\n DomainFactoryRepo.type,\r\n appObjects\r\n );\r\n }\r\n\r\n /**\r\n * Orchestrates the setup of the entire domain layer in the correct sequence.\r\n * Calls each setup phase on all factories before proceeding to the next phase.\r\n * This ensures cross-domain dependencies are properly resolved.\r\n */\r\n setupDomain = () => {\r\n const allFactories = this.getAll();\r\n\r\n // Phase 1: Set up all entities first\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.setupEntities();\r\n });\r\n\r\n // Phase 2: Set up all use cases next\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.setupUCs();\r\n });\r\n\r\n // Phase 3: Set up all presentation managers\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.setupPMs();\r\n });\r\n\r\n // Phase 4: Perform final setup operations\r\n allFactories.forEach((domainFactory) => {\r\n domainFactory.finalSetup();\r\n });\r\n };\r\n\r\n /**\r\n * Retrieves a domain factory by its name.\r\n * @param name The name of the domain factory to find\r\n * @returns The matching domain factory or undefined if not found\r\n */\r\n getByName(name: string): DomainFactory | undefined {\r\n const allFactories = this.getAll();\r\n return allFactories.find((factory) => factory.factoryName === name);\r\n }\r\n\r\n /**\r\n * Creates a new DomainFactoryRepo and registers it with the given AppObject.\r\n * @param appObject The parent AppObject this component will be attached to\r\n */\r\n constructor(appObject: AppObject) {\r\n super(appObject, DomainFactoryRepo.type);\r\n }\r\n}\r\n\r\nexport function makeDomainFactoryRepo(appObjects: AppObjectRepo) {\r\n const appObject = appObjects.getOrCreate(\"DomainFactoryRepo\");\r\n return new DomainFactoryRepo(appObject);\r\n}"]}
@@ -0,0 +1,60 @@
1
+ import { DomainFactory } from "../../DomainFactories";
2
+ import { makeSingletonEntityExample } from "../Entities/ExampleSingletonEntity";
3
+ import { makeExampleSingletonPM } from "../PMs/ExampleSingletonPM";
4
+ import { makeToggleExampleBooleanUC } from "../UCs/ToggleExampleBooleanUC";
5
+ /**
6
+ * Factory responsible for setting up the Example Feature domain components.
7
+ *
8
+ * This factory initializes all entities, use cases, and presentation models
9
+ * required for the Example Feature functionality. It follows the domain-driven
10
+ * design pattern by organizing components into their respective layers.
11
+ *
12
+ * @extends DomainFactory
13
+ */
14
+ export class ExampleFeatureFactory extends DomainFactory {
15
+ constructor() {
16
+ super(...arguments);
17
+ this.factoryName = "ExampleFeatureFactory";
18
+ }
19
+ /**
20
+ * Sets up all entities required for the Example Feature.
21
+ *
22
+ * Initializes singleton entities that maintain the state and business
23
+ * logic for the example feature functionality.
24
+ */
25
+ setupEntities() {
26
+ makeSingletonEntityExample(this.appObject);
27
+ }
28
+ /**
29
+ * Sets up all use cases for the Example Feature.
30
+ *
31
+ * Initializes use cases that define the business operations and
32
+ * workflows available in the example feature.
33
+ */
34
+ setupUCs() {
35
+ makeToggleExampleBooleanUC(this.appObject);
36
+ }
37
+ /**
38
+ * Sets up all presentation models for the Example Feature.
39
+ *
40
+ * Initializes presentation models that handle the view logic and
41
+ * state management for UI components related to the example feature.
42
+ */
43
+ setupPMs() {
44
+ makeExampleSingletonPM(this.appObject);
45
+ }
46
+ /**
47
+ * Performs any final setup operations after all components are initialized.
48
+ *
49
+ * This method is called after entities, use cases, and presentation models
50
+ * have been set up. Currently no additional setup is required for this feature.
51
+ */
52
+ finalSetup() {
53
+ // No additional setup required for this feature
54
+ }
55
+ }
56
+ export function makeExampleFeatureFactory(appObjects) {
57
+ const appObject = appObjects.getOrCreate("ExampleFeatureFactory");
58
+ return new ExampleFeatureFactory(appObject);
59
+ }
60
+ //# sourceMappingURL=ExampleFeatureFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExampleFeatureFactory.js","sourceRoot":"","sources":["../../../../src/ExampleFeature/Factory/ExampleFeatureFactory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAE3E;;;;;;;;GAQG;AACH,MAAM,OAAO,qBAAsB,SAAQ,aAAa;IAAxD;;QAEC,gBAAW,GAAG,uBAAuB,CAAC;IA6CvC,CAAC;IA3CA;;;;;OAKG;IACH,aAAa;QAEZ,0BAA0B,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;OAKG;IACH,QAAQ;QAEP,0BAA0B,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;OAKG;IACH,QAAQ;QAEP,sBAAsB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAED;;;;;OAKG;IACH,UAAU;QAET,gDAAgD;IACjD,CAAC;CACD;AAED,MAAM,UAAU,yBAAyB,CAAC,UAAyB;IAClE,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,uBAAuB,CAAC,CAAC;IAClE,OAAO,IAAI,qBAAqB,CAAC,SAAS,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["import { AppObjectRepo } from \"../../AppObject\";\r\nimport { DomainFactory } from \"../../DomainFactories\";\r\nimport { makeSingletonEntityExample } from \"../Entities/ExampleSingletonEntity\";\r\nimport { makeExampleSingletonPM } from \"../PMs/ExampleSingletonPM\";\r\nimport { makeToggleExampleBooleanUC } from \"../UCs/ToggleExampleBooleanUC\";\r\n\r\n/**\r\n * Factory responsible for setting up the Example Feature domain components.\r\n * \r\n * This factory initializes all entities, use cases, and presentation models\r\n * required for the Example Feature functionality. It follows the domain-driven\r\n * design pattern by organizing components into their respective layers.\r\n * \r\n * @extends DomainFactory\r\n */\r\nexport class ExampleFeatureFactory extends DomainFactory\r\n{\r\n\tfactoryName = \"ExampleFeatureFactory\";\r\n\r\n\t/**\r\n\t * Sets up all entities required for the Example Feature.\r\n\t * \r\n\t * Initializes singleton entities that maintain the state and business\r\n\t * logic for the example feature functionality.\r\n\t */\r\n\tsetupEntities(): void\r\n\t{\r\n\t\tmakeSingletonEntityExample(this.appObject);\r\n\t}\r\n\r\n\t/**\r\n\t * Sets up all use cases for the Example Feature.\r\n\t * \r\n\t * Initializes use cases that define the business operations and\r\n\t * workflows available in the example feature.\r\n\t */\r\n\tsetupUCs(): void\r\n\t{\r\n\t\tmakeToggleExampleBooleanUC(this.appObject);\r\n\t}\r\n\r\n\t/**\r\n\t * Sets up all presentation models for the Example Feature.\r\n\t * \r\n\t * Initializes presentation models that handle the view logic and\r\n\t * state management for UI components related to the example feature.\r\n\t */\r\n\tsetupPMs(): void\r\n\t{\r\n\t\tmakeExampleSingletonPM(this.appObject);\r\n\t}\r\n\r\n\t/**\r\n\t * Performs any final setup operations after all components are initialized.\r\n\t * \r\n\t * This method is called after entities, use cases, and presentation models\r\n\t * have been set up. Currently no additional setup is required for this feature.\r\n\t */\r\n\tfinalSetup(): void\r\n\t{\r\n\t\t// No additional setup required for this feature\r\n\t}\r\n}\r\n\r\nexport function makeExampleFeatureFactory(appObjects: AppObjectRepo):ExampleFeatureFactory {\r\n\tconst appObject = appObjects.getOrCreate(\"ExampleFeatureFactory\");\r\n\treturn new ExampleFeatureFactory(appObject);\r\n}"]}
@@ -164,16 +164,15 @@ Vector2.Dot = (a, b) => {
164
164
  return a.x * b.x + a.y * b.y;
165
165
  };
166
166
  /**
167
- * Calculates the dot product between Vectors A and B
167
+ * Calculates the angle between Vectors A and B
168
168
  * @param a Vector A
169
169
  * @param b Vector B
170
- * @returns A . B
170
+ * @returns The angle between A and B
171
171
  */
172
172
  Vector2.AngleBetween = (a, b) => {
173
- const dot = Vector2.Dot(a, b);
174
- const magnitudes = a.magnitude * b.magnitude;
175
- const angRadians = Math.acos(dot / magnitudes);
176
- return Angle.FromRadians(angRadians);
173
+ const angleA = Math.atan2(a.y, a.x);
174
+ const angleB = Math.atan2(b.y, b.x);
175
+ return Angle.FromRadians(angleB - angleA);
177
176
  };
178
177
  /**
179
178
  * Calculates the Cross product between Vectors A and B