@vived/host 4.6.0 → 4.8.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 (177) hide show
  1. package/dist/cjs/Assets/UCs/GetAssetBlobURLUC.js +104 -27
  2. package/dist/cjs/Assets/UCs/GetAssetBlobURLUC.js.map +1 -1
  3. package/dist/cjs/Assets/UCs/GetAssetFileUC.js +111 -34
  4. package/dist/cjs/Assets/UCs/GetAssetFileUC.js.map +1 -1
  5. package/dist/cjs/Cache/Controllers/clearCache.js +13 -0
  6. package/dist/cjs/Cache/Controllers/clearCache.js.map +1 -0
  7. package/dist/cjs/Cache/Controllers/index.js +18 -0
  8. package/dist/cjs/Cache/Controllers/index.js.map +1 -0
  9. package/dist/cjs/Cache/Entities/AssetCacheEntity.js +95 -0
  10. package/dist/cjs/Cache/Entities/AssetCacheEntity.js.map +1 -0
  11. package/dist/cjs/Cache/Entities/CacheEntity.js +54 -0
  12. package/dist/cjs/Cache/Entities/CacheEntity.js.map +1 -0
  13. package/dist/cjs/Cache/Entities/ScriptCacheEntity.js +137 -0
  14. package/dist/cjs/Cache/Entities/ScriptCacheEntity.js.map +1 -0
  15. package/dist/cjs/Cache/Entities/index.js +25 -0
  16. package/dist/cjs/Cache/Entities/index.js.map +1 -0
  17. package/dist/cjs/Cache/Factories/index.js +18 -0
  18. package/dist/cjs/Cache/Factories/index.js.map +1 -0
  19. package/dist/cjs/Cache/Factories/setupCache.js +27 -0
  20. package/dist/cjs/Cache/Factories/setupCache.js.map +1 -0
  21. package/dist/cjs/Cache/Mocks/MockCacheEntity.js +22 -0
  22. package/dist/cjs/Cache/Mocks/MockCacheEntity.js.map +1 -0
  23. package/dist/cjs/Cache/Mocks/MockGetAssetFromCacheUC.js +19 -0
  24. package/dist/cjs/Cache/Mocks/MockGetAssetFromCacheUC.js.map +1 -0
  25. package/dist/cjs/Cache/Mocks/MockGetScriptFromCacheUC.js +22 -0
  26. package/dist/cjs/Cache/Mocks/MockGetScriptFromCacheUC.js.map +1 -0
  27. package/dist/cjs/Cache/Mocks/MockStoreAssetInCacheUC.js +17 -0
  28. package/dist/cjs/Cache/Mocks/MockStoreAssetInCacheUC.js.map +1 -0
  29. package/dist/cjs/Cache/Mocks/MockStoreScriptInCacheUC.js +22 -0
  30. package/dist/cjs/Cache/Mocks/MockStoreScriptInCacheUC.js.map +1 -0
  31. package/dist/cjs/Cache/Mocks/index.js +22 -0
  32. package/dist/cjs/Cache/Mocks/index.js.map +1 -0
  33. package/dist/cjs/Cache/UCs/GetAssetFromCacheUC.js +40 -0
  34. package/dist/cjs/Cache/UCs/GetAssetFromCacheUC.js.map +1 -0
  35. package/dist/cjs/Cache/UCs/GetScriptFromCacheUC.js +49 -0
  36. package/dist/cjs/Cache/UCs/GetScriptFromCacheUC.js.map +1 -0
  37. package/dist/cjs/Cache/UCs/StoreAssetInCacheUC.js +39 -0
  38. package/dist/cjs/Cache/UCs/StoreAssetInCacheUC.js.map +1 -0
  39. package/dist/cjs/Cache/UCs/StoreScriptInCacheUC.js +48 -0
  40. package/dist/cjs/Cache/UCs/StoreScriptInCacheUC.js.map +1 -0
  41. package/dist/cjs/Cache/UCs/index.js +26 -0
  42. package/dist/cjs/Cache/UCs/index.js.map +1 -0
  43. package/dist/cjs/Cache/index.js +21 -0
  44. package/dist/cjs/Cache/index.js.map +1 -0
  45. package/dist/cjs/StateMachine/Entities/HostEditingStateEntity.js +62 -0
  46. package/dist/cjs/StateMachine/Entities/HostEditingStateEntity.js.map +1 -1
  47. package/dist/cjs/StateMachine/Entities/HostStateEntity.js +91 -2
  48. package/dist/cjs/StateMachine/Entities/HostStateEntity.js.map +1 -1
  49. package/dist/cjs/StateMachine/Entities/HostStateMachine.js +127 -0
  50. package/dist/cjs/StateMachine/Entities/HostStateMachine.js.map +1 -1
  51. package/dist/cjs/StateMachine/Mocks/MockHostStateEntity.js +1 -0
  52. package/dist/cjs/StateMachine/Mocks/MockHostStateEntity.js.map +1 -1
  53. package/dist/cjs/StateMachine/PMs/HostStatePM.js +6 -2
  54. package/dist/cjs/StateMachine/PMs/HostStatePM.js.map +1 -1
  55. package/dist/cjs/StateMachine/UCs/DeleteStateUC.js +1 -1
  56. package/dist/cjs/StateMachine/UCs/DeleteStateUC.js.map +1 -1
  57. package/dist/cjs/StateMachine/UCs/DuplicateStateUC.js +1 -1
  58. package/dist/cjs/StateMachine/UCs/DuplicateStateUC.js.map +1 -1
  59. package/dist/cjs/StateMachine/UCs/SavePersistentStates.js.map +1 -1
  60. package/dist/cjs/index.js +1 -0
  61. package/dist/cjs/index.js.map +1 -1
  62. package/dist/esm/Assets/UCs/GetAssetBlobURLUC.js +104 -27
  63. package/dist/esm/Assets/UCs/GetAssetBlobURLUC.js.map +1 -1
  64. package/dist/esm/Assets/UCs/GetAssetFileUC.js +111 -34
  65. package/dist/esm/Assets/UCs/GetAssetFileUC.js.map +1 -1
  66. package/dist/esm/Cache/Controllers/clearCache.js +10 -0
  67. package/dist/esm/Cache/Controllers/clearCache.js.map +1 -0
  68. package/dist/esm/Cache/Controllers/index.js +2 -0
  69. package/dist/esm/Cache/Controllers/index.js.map +1 -0
  70. package/dist/esm/Cache/Entities/AssetCacheEntity.js +90 -0
  71. package/dist/esm/Cache/Entities/AssetCacheEntity.js.map +1 -0
  72. package/dist/esm/Cache/Entities/CacheEntity.js +49 -0
  73. package/dist/esm/Cache/Entities/CacheEntity.js.map +1 -0
  74. package/dist/esm/Cache/Entities/ScriptCacheEntity.js +132 -0
  75. package/dist/esm/Cache/Entities/ScriptCacheEntity.js.map +1 -0
  76. package/dist/esm/Cache/Entities/index.js +9 -0
  77. package/dist/esm/Cache/Entities/index.js.map +1 -0
  78. package/dist/esm/Cache/Factories/index.js +2 -0
  79. package/dist/esm/Cache/Factories/index.js.map +1 -0
  80. package/dist/esm/Cache/Factories/setupCache.js +24 -0
  81. package/dist/esm/Cache/Factories/setupCache.js.map +1 -0
  82. package/dist/esm/Cache/Mocks/MockCacheEntity.js +17 -0
  83. package/dist/esm/Cache/Mocks/MockCacheEntity.js.map +1 -0
  84. package/dist/esm/Cache/Mocks/MockGetAssetFromCacheUC.js +14 -0
  85. package/dist/esm/Cache/Mocks/MockGetAssetFromCacheUC.js.map +1 -0
  86. package/dist/esm/Cache/Mocks/MockGetScriptFromCacheUC.js +17 -0
  87. package/dist/esm/Cache/Mocks/MockGetScriptFromCacheUC.js.map +1 -0
  88. package/dist/esm/Cache/Mocks/MockStoreAssetInCacheUC.js +12 -0
  89. package/dist/esm/Cache/Mocks/MockStoreAssetInCacheUC.js.map +1 -0
  90. package/dist/esm/Cache/Mocks/MockStoreScriptInCacheUC.js +17 -0
  91. package/dist/esm/Cache/Mocks/MockStoreScriptInCacheUC.js.map +1 -0
  92. package/dist/esm/Cache/Mocks/index.js +6 -0
  93. package/dist/esm/Cache/Mocks/index.js.map +1 -0
  94. package/dist/esm/Cache/UCs/GetAssetFromCacheUC.js +35 -0
  95. package/dist/esm/Cache/UCs/GetAssetFromCacheUC.js.map +1 -0
  96. package/dist/esm/Cache/UCs/GetScriptFromCacheUC.js +44 -0
  97. package/dist/esm/Cache/UCs/GetScriptFromCacheUC.js.map +1 -0
  98. package/dist/esm/Cache/UCs/StoreAssetInCacheUC.js +34 -0
  99. package/dist/esm/Cache/UCs/StoreAssetInCacheUC.js.map +1 -0
  100. package/dist/esm/Cache/UCs/StoreScriptInCacheUC.js +43 -0
  101. package/dist/esm/Cache/UCs/StoreScriptInCacheUC.js.map +1 -0
  102. package/dist/esm/Cache/UCs/index.js +10 -0
  103. package/dist/esm/Cache/UCs/index.js.map +1 -0
  104. package/dist/esm/Cache/index.js +5 -0
  105. package/dist/esm/Cache/index.js.map +1 -0
  106. package/dist/esm/StateMachine/Entities/HostEditingStateEntity.js +62 -0
  107. package/dist/esm/StateMachine/Entities/HostEditingStateEntity.js.map +1 -1
  108. package/dist/esm/StateMachine/Entities/HostStateEntity.js +90 -1
  109. package/dist/esm/StateMachine/Entities/HostStateEntity.js.map +1 -1
  110. package/dist/esm/StateMachine/Entities/HostStateMachine.js +127 -0
  111. package/dist/esm/StateMachine/Entities/HostStateMachine.js.map +1 -1
  112. package/dist/esm/StateMachine/Mocks/MockHostStateEntity.js +2 -1
  113. package/dist/esm/StateMachine/Mocks/MockHostStateEntity.js.map +1 -1
  114. package/dist/esm/StateMachine/PMs/HostStatePM.js +7 -3
  115. package/dist/esm/StateMachine/PMs/HostStatePM.js.map +1 -1
  116. package/dist/esm/StateMachine/UCs/DeleteStateUC.js +1 -1
  117. package/dist/esm/StateMachine/UCs/DeleteStateUC.js.map +1 -1
  118. package/dist/esm/StateMachine/UCs/DuplicateStateUC.js +1 -1
  119. package/dist/esm/StateMachine/UCs/DuplicateStateUC.js.map +1 -1
  120. package/dist/esm/StateMachine/UCs/SavePersistentStates.js.map +1 -1
  121. package/dist/esm/index.js +1 -0
  122. package/dist/esm/index.js.map +1 -1
  123. package/dist/types/Assets/UCs/GetAssetBlobURLUC.d.ts.map +1 -1
  124. package/dist/types/Cache/Controllers/clearCache.d.ts +3 -0
  125. package/dist/types/Cache/Controllers/clearCache.d.ts.map +1 -0
  126. package/dist/types/Cache/Controllers/index.d.ts +2 -0
  127. package/dist/types/Cache/Controllers/index.d.ts.map +1 -0
  128. package/dist/types/Cache/Entities/AssetCacheEntity.d.ts +43 -0
  129. package/dist/types/Cache/Entities/AssetCacheEntity.d.ts.map +1 -0
  130. package/dist/types/Cache/Entities/CacheEntity.d.ts +57 -0
  131. package/dist/types/Cache/Entities/CacheEntity.d.ts.map +1 -0
  132. package/dist/types/Cache/Entities/ScriptCacheEntity.d.ts +64 -0
  133. package/dist/types/Cache/Entities/ScriptCacheEntity.d.ts.map +1 -0
  134. package/dist/types/Cache/Entities/index.d.ts +9 -0
  135. package/dist/types/Cache/Entities/index.d.ts.map +1 -0
  136. package/dist/types/Cache/Factories/index.d.ts +2 -0
  137. package/dist/types/Cache/Factories/index.d.ts.map +1 -0
  138. package/dist/types/Cache/Factories/setupCache.d.ts +6 -0
  139. package/dist/types/Cache/Factories/setupCache.d.ts.map +1 -0
  140. package/dist/types/Cache/Mocks/MockCacheEntity.d.ts +13 -0
  141. package/dist/types/Cache/Mocks/MockCacheEntity.d.ts.map +1 -0
  142. package/dist/types/Cache/Mocks/MockGetAssetFromCacheUC.d.ts +8 -0
  143. package/dist/types/Cache/Mocks/MockGetAssetFromCacheUC.d.ts.map +1 -0
  144. package/dist/types/Cache/Mocks/MockGetScriptFromCacheUC.d.ts +9 -0
  145. package/dist/types/Cache/Mocks/MockGetScriptFromCacheUC.d.ts.map +1 -0
  146. package/dist/types/Cache/Mocks/MockStoreAssetInCacheUC.d.ts +8 -0
  147. package/dist/types/Cache/Mocks/MockStoreAssetInCacheUC.d.ts.map +1 -0
  148. package/dist/types/Cache/Mocks/MockStoreScriptInCacheUC.d.ts +9 -0
  149. package/dist/types/Cache/Mocks/MockStoreScriptInCacheUC.d.ts.map +1 -0
  150. package/dist/types/Cache/Mocks/index.d.ts +6 -0
  151. package/dist/types/Cache/Mocks/index.d.ts.map +1 -0
  152. package/dist/types/Cache/UCs/GetAssetFromCacheUC.d.ts +8 -0
  153. package/dist/types/Cache/UCs/GetAssetFromCacheUC.d.ts.map +1 -0
  154. package/dist/types/Cache/UCs/GetScriptFromCacheUC.d.ts +13 -0
  155. package/dist/types/Cache/UCs/GetScriptFromCacheUC.d.ts.map +1 -0
  156. package/dist/types/Cache/UCs/StoreAssetInCacheUC.d.ts +8 -0
  157. package/dist/types/Cache/UCs/StoreAssetInCacheUC.d.ts.map +1 -0
  158. package/dist/types/Cache/UCs/StoreScriptInCacheUC.d.ts +13 -0
  159. package/dist/types/Cache/UCs/StoreScriptInCacheUC.d.ts.map +1 -0
  160. package/dist/types/Cache/UCs/index.d.ts +10 -0
  161. package/dist/types/Cache/UCs/index.d.ts.map +1 -0
  162. package/dist/types/Cache/index.d.ts +5 -0
  163. package/dist/types/Cache/index.d.ts.map +1 -0
  164. package/dist/types/StateMachine/Entities/HostEditingStateEntity.d.ts +42 -0
  165. package/dist/types/StateMachine/Entities/HostEditingStateEntity.d.ts.map +1 -1
  166. package/dist/types/StateMachine/Entities/HostStateEntity.d.ts +72 -5
  167. package/dist/types/StateMachine/Entities/HostStateEntity.d.ts.map +1 -1
  168. package/dist/types/StateMachine/Entities/HostStateMachine.d.ts +77 -0
  169. package/dist/types/StateMachine/Entities/HostStateMachine.d.ts.map +1 -1
  170. package/dist/types/StateMachine/Mocks/MockHostStateEntity.d.ts +2 -1
  171. package/dist/types/StateMachine/Mocks/MockHostStateEntity.d.ts.map +1 -1
  172. package/dist/types/StateMachine/PMs/HostStatePM.d.ts +2 -0
  173. package/dist/types/StateMachine/PMs/HostStatePM.d.ts.map +1 -1
  174. package/dist/types/StateMachine/UCs/SavePersistentStates.d.ts.map +1 -1
  175. package/dist/types/index.d.ts +1 -0
  176. package/dist/types/index.d.ts.map +1 -1
  177. package/package.json +1 -1
@@ -1,15 +1,39 @@
1
1
  import { MemoizedBoolean } from "@vived/core";
2
2
  import { getSingletonComponent, AppObjectEntity } from "@vived/core";
3
3
  import { HostStateMachine } from "./HostStateMachine";
4
+ /**
5
+ * HostEditingStateEntity handles the editing workflow for state entities.
6
+ *
7
+ * This singleton component manages the process of creating new states or editing
8
+ * existing states in the host state machine. It tracks changes made during editing,
9
+ * maintains the original state for cancellation/rollback, and provides validation.
10
+ *
11
+ * The component implements a standard editing pattern:
12
+ * 1. Start editing (startEditing) or create new (startNewState)
13
+ * 2. Make changes to the editingState directly
14
+ * 3. Complete with either finishEditing (commit) or cancelEditState (rollback)
15
+ *
16
+ * This entity is a critical part of the state authoring workflow and works closely
17
+ * with HostStateMachine and HostStateEntity.
18
+ */
4
19
  export class HostEditingStateEntity extends AppObjectEntity {
5
20
  static get(appObjects) {
6
21
  return getSingletonComponent(HostEditingStateEntity.type, appObjects);
7
22
  }
8
23
  }
9
24
  HostEditingStateEntity.type = "HostEditingStateEntity";
25
+ /**
26
+ * Factory function for creating a HostEditingStateEntity instance
27
+ * @param appObject The AppObject to associate with this entity
28
+ * @returns A new HostEditingStateEntity instance
29
+ */
10
30
  export function makeHostEditingStateEntity(appObject) {
11
31
  return new HostEditingStateEntityImp(appObject);
12
32
  }
33
+ /**
34
+ * Implementation of the HostEditingStateEntity abstract class
35
+ * Manages the state editing workflow and tracks changes
36
+ */
13
37
  class HostEditingStateEntityImp extends HostEditingStateEntity {
14
38
  get editingState() {
15
39
  return this._editingState;
@@ -29,6 +53,10 @@ class HostEditingStateEntityImp extends HostEditingStateEntity {
29
53
  this._stateValidationMessage = val;
30
54
  this.notifyOnChange();
31
55
  }
56
+ /**
57
+ * Reference to the HostStateMachine singleton
58
+ * Used for creating and managing states
59
+ */
32
60
  get hostStateMachine() {
33
61
  return this.getCachedSingleton(HostStateMachine.type);
34
62
  }
@@ -38,7 +66,16 @@ class HostEditingStateEntityImp extends HostEditingStateEntity {
38
66
  constructor(appObject) {
39
67
  super(appObject, HostEditingStateEntity.type);
40
68
  this._isNewState = false;
69
+ /**
70
+ * Tracks whether changes have been made to the state being edited
71
+ * Uses a memoized value to efficiently notify observers only when value changes
72
+ */
41
73
  this.memoizedSomethingHasChanged = new MemoizedBoolean(false, this.notifyOnChange);
74
+ /**
75
+ * Compares the current state with the original state to detect changes
76
+ * Performs deep comparison of all relevant properties
77
+ * @returns true if changes were detected, false otherwise
78
+ */
42
79
  this.checkForChange = () => {
43
80
  if (!this._editingState)
44
81
  return false;
@@ -66,9 +103,17 @@ class HostEditingStateEntityImp extends HostEditingStateEntity {
66
103
  return true;
67
104
  return false;
68
105
  };
106
+ /**
107
+ * Observer callback for state changes
108
+ * Updates the somethingHasChanged flag when the state being edited changes
109
+ */
69
110
  this.onStateEntityChange = () => {
70
111
  this.memoizedSomethingHasChanged.val = this.checkForChange();
71
112
  };
113
+ /**
114
+ * Creates a new state and begins editing it
115
+ * @returns The newly created state entity or undefined if creation failed
116
+ */
72
117
  this.startNewState = () => {
73
118
  if (!this.hostStateMachine)
74
119
  return;
@@ -79,12 +124,21 @@ class HostEditingStateEntityImp extends HostEditingStateEntity {
79
124
  this.memoizedSomethingHasChanged.val = true;
80
125
  return this._editingState;
81
126
  };
127
+ /**
128
+ * Begins editing an existing state
129
+ * @param state The state entity to edit
130
+ */
82
131
  this.startEditing = (state) => {
83
132
  this._editingState = state;
84
133
  this.originalStateData = state.getDTO();
85
134
  this._editingState.addChangeObserver(this.onStateEntityChange);
86
135
  this.notifyOnChange();
87
136
  };
137
+ /**
138
+ * Cancels editing and reverts changes
139
+ * For new states, removes them from the state machine
140
+ * For existing states, restores the original values
141
+ */
88
142
  this.cancelEditState = () => {
89
143
  if (!this._editingState)
90
144
  return;
@@ -96,9 +150,17 @@ class HostEditingStateEntityImp extends HostEditingStateEntity {
96
150
  }
97
151
  this.resetInternalState();
98
152
  };
153
+ /**
154
+ * Completes editing, keeping all changes
155
+ * Simply cleans up the internal state without reverting changes
156
+ */
99
157
  this.finishEditing = () => {
100
158
  this.resetInternalState();
101
159
  };
160
+ /**
161
+ * Resets the internal state after editing is complete
162
+ * Cleans up observers and notifies clients of the change
163
+ */
102
164
  this.resetInternalState = () => {
103
165
  if (!this._editingState)
104
166
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"HostEditingStateEntity.js","sourceRoot":"","sources":["../../../../src/StateMachine/Entities/HostEditingStateEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EACL,qBAAqB,EAErB,eAAe,EAEhB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,OAAgB,sBAAuB,SAAQ,eAAe;IAclE,MAAM,CAAC,GAAG,CAAC,UAAyB;QAClC,OAAO,qBAAqB,CAC1B,sBAAsB,CAAC,IAAI,EAC3B,UAAU,CACX,CAAC;IACJ,CAAC;;AAlBM,2BAAI,GAAG,wBAAwB,CAAC;AAqBzC,MAAM,UAAU,0BAA0B,CACxC,SAAoB;IAEpB,OAAO,IAAI,yBAAyB,CAAC,SAAS,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,yBAA0B,SAAQ,sBAAsB;IAI5D,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC;IAC1C,CAAC;IAGD,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAGD,IAAI,sBAAsB;QACxB,OAAO,IAAI,CAAC,uBAAuB,CAAC;IACtC,CAAC;IACD,IAAI,sBAAsB,CAAC,GAAuB;QAChD,IAAI,IAAI,CAAC,uBAAuB,KAAK,GAAG;YAAE,OAAO;QAEjD,IAAI,CAAC,uBAAuB,GAAG,GAAG,CAAC;QACnC,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAED,IAAY,gBAAgB;QAC1B,OAAO,IAAI,CAAC,kBAAkB,CAAmB,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC1E,CAAC;IAMD,IAAI,mBAAmB;QACrB,OAAO,IAAI,CAAC,2BAA2B,CAAC,GAAG,CAAC;IAC9C,CAAC;IAsFD,YAAY,SAAoB;QAC9B,KAAK,CAAC,SAAS,EAAE,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAjHxC,gBAAW,GAAG,KAAK,CAAC;QAoBpB,gCAA2B,GAAG,IAAI,eAAe,CACvD,KAAK,EACL,IAAI,CAAC,cAAc,CACpB,CAAC;QAKM,mBAAc,GAAG,GAAG,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,aAAa;gBAAE,OAAO,KAAK,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,iBAAiB;gBAAE,OAAO,IAAI,CAAC;YAEzC,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAC;YAEzE,IAAI,IAAI,CAAC,aAAa,CAAC,gBAAgB,KAAK,IAAI,CAAC,iBAAiB,CAAC,QAAQ;gBACzE,OAAO,IAAI,CAAC;YAEd,IACE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM;gBAEzE,OAAO,IAAI,CAAC;YACd,IAAI,iBAAiB,GAAG,KAAK,CAAC;YAC9B,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,cAAc,EAAE,CAAC,EAAE,EAAE;gBACtD,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC1D,IAAI,eAAe,KAAK,cAAc,EAAE,CAAC;oBACvC,iBAAiB,GAAG,IAAI,CAAC;gBAC3B,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,iBAAiB,EAAE,CAAC;gBACtB,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;YACvE,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,iBAAiB,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;YACxE,IAAI,iBAAiB,KAAK,YAAY;gBAAE,OAAO,IAAI,CAAC;YAEpD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEM,wBAAmB,GAAG,GAAS,EAAE;YACvC,IAAI,CAAC,2BAA2B,CAAC,GAAG,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC/D,CAAC,CAAC;QAEF,kBAAa,GAAG,GAAgC,EAAE;YAChD,IAAI,CAAC,IAAI,CAAC,gBAAgB;gBAAE,OAAO;YAEnC,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;YACnC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC;YAC5D,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAC/D,IAAI,CAAC,2BAA2B,CAAC,GAAG,GAAG,IAAI,CAAC;YAE5C,OAAO,IAAI,CAAC,aAAa,CAAC;QAC5B,CAAC,CAAC;QAEF,iBAAY,GAAG,CAAC,KAAsB,EAAQ,EAAE;YAC9C,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;YAE3B,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YACxC,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAE/D,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,CAAC,CAAC;QAEF,oBAAe,GAAG,GAAS,EAAE;YAC3B,IAAI,CAAC,IAAI,CAAC,aAAa;gBAAE,OAAO;YAEhC,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC3B,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAC5D,CAAC;YAED,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC,CAAC;QAEF,kBAAa,GAAG,GAAS,EAAE;YACzB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC,CAAC;QAEM,uBAAkB,GAAG,GAAG,EAAE;YAChC,IAAI,CAAC,IAAI,CAAC,aAAa;gBAAE,OAAO;YAEhC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAClE,IAAI,CAAC,uBAAuB,GAAG,SAAS,CAAC;YACzC,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;YAC/B,IAAI,CAAC,2BAA2B,CAAC,GAAG,GAAG,KAAK,CAAC;YAC7C,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,CAAC,CAAC;QAIA,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;CACF","sourcesContent":["import { MemoizedBoolean } from \"@vived/core\";\r\nimport {\r\n getSingletonComponent,\r\n AppObject,\r\n AppObjectEntity,\r\n AppObjectRepo\r\n} from \"@vived/core\";\r\nimport { HostStateEntity, StateDTO } from \"./HostStateEntity\";\r\nimport { HostStateMachine } from \"./HostStateMachine\";\r\n\r\nexport abstract class HostEditingStateEntity extends AppObjectEntity {\r\n static type = \"HostEditingStateEntity\";\r\n\r\n abstract get isEditing(): boolean;\r\n abstract get isNewState(): boolean;\r\n abstract get editingState(): HostStateEntity | undefined;\r\n abstract get somethingHasChanged(): boolean;\r\n abstract stateValidationMessage?: string;\r\n\r\n abstract startNewState(): HostStateEntity | undefined;\r\n abstract startEditing(state: HostStateEntity): void;\r\n abstract cancelEditState(): void;\r\n abstract finishEditing(): void;\r\n\r\n static get(appObjects: AppObjectRepo) {\r\n return getSingletonComponent<HostEditingStateEntity>(\r\n HostEditingStateEntity.type,\r\n appObjects\r\n );\r\n }\r\n}\r\n\r\nexport function makeHostEditingStateEntity(\r\n appObject: AppObject\r\n): HostEditingStateEntity {\r\n return new HostEditingStateEntityImp(appObject);\r\n}\r\n\r\nclass HostEditingStateEntityImp extends HostEditingStateEntity {\r\n private originalStateData?: StateDTO;\r\n \r\n private _editingState?: HostStateEntity;\r\n get editingState() {\r\n return this._editingState;\r\n }\r\n\r\n get isEditing(): boolean {\r\n return this._editingState !== undefined;\r\n }\r\n\r\n private _isNewState = false;\r\n get isNewState(): boolean {\r\n return this._isNewState;\r\n }\r\n\r\n private _stateValidationMessage?: string | undefined;\r\n get stateValidationMessage(): string | undefined {\r\n return this._stateValidationMessage;\r\n }\r\n set stateValidationMessage(val: string | undefined) {\r\n if (this._stateValidationMessage === val) return;\r\n\r\n this._stateValidationMessage = val;\r\n this.notifyOnChange();\r\n }\r\n\r\n private get hostStateMachine() {\r\n return this.getCachedSingleton<HostStateMachine>(HostStateMachine.type);\r\n }\r\n\r\n private memoizedSomethingHasChanged = new MemoizedBoolean(\r\n false,\r\n this.notifyOnChange\r\n );\r\n get somethingHasChanged(): boolean {\r\n return this.memoizedSomethingHasChanged.val;\r\n }\r\n\r\n private checkForChange = () => {\r\n if (!this._editingState) return false;\r\n if (!this.originalStateData) return true;\r\n\r\n if (this._editingState.name !== this.originalStateData.name) return true;\r\n\r\n if (this._editingState.expectedResponse !== this.originalStateData.response)\r\n return true;\r\n\r\n if (\r\n this._editingState.assets.length !== this.originalStateData.assets.length\r\n )\r\n return true;\r\n let assetsHaveChanged = false;\r\n this._editingState.assets.forEach((currentAssetID, i) => {\r\n const originalAssetId = this.originalStateData!.assets[i];\r\n if (originalAssetId !== currentAssetID) {\r\n assetsHaveChanged = true;\r\n }\r\n });\r\n\r\n if (assetsHaveChanged) {\r\n return true;\r\n }\r\n\r\n const currentDataString = JSON.stringify(this._editingState.stateData);\r\n const originalData = JSON.stringify(this.originalStateData?.data ?? \"\");\r\n if (currentDataString !== originalData) return true;\r\n\r\n return false;\r\n };\r\n\r\n private onStateEntityChange = (): void => {\r\n this.memoizedSomethingHasChanged.val = this.checkForChange();\r\n };\r\n\r\n startNewState = (): HostStateEntity | undefined => {\r\n if (!this.hostStateMachine) return;\r\n\r\n this.originalStateData = undefined;\r\n this._isNewState = true;\r\n this._editingState = this.hostStateMachine.createNewState();\r\n this._editingState.addChangeObserver(this.onStateEntityChange);\r\n this.memoizedSomethingHasChanged.val = true;\r\n\r\n return this._editingState;\r\n };\r\n\r\n startEditing = (state: HostStateEntity): void => {\r\n this._editingState = state;\r\n\r\n this.originalStateData = state.getDTO();\r\n this._editingState.addChangeObserver(this.onStateEntityChange);\r\n\r\n this.notifyOnChange();\r\n };\r\n\r\n cancelEditState = (): void => {\r\n if (!this._editingState) return;\r\n\r\n if (this.originalStateData) {\r\n this._editingState.setDTO(this.originalStateData);\r\n } else {\r\n this.hostStateMachine?.deleteState(this._editingState.id);\r\n }\r\n\r\n this.resetInternalState();\r\n };\r\n\r\n finishEditing = (): void => {\r\n this.resetInternalState();\r\n };\r\n\r\n private resetInternalState = () => {\r\n if (!this._editingState) return;\r\n\r\n this._isNewState = false;\r\n this._editingState.removeChangeObserver(this.onStateEntityChange);\r\n this._stateValidationMessage = undefined;\r\n this._editingState = undefined;\r\n this.memoizedSomethingHasChanged.val = false;\r\n this.notifyOnChange();\r\n };\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, HostEditingStateEntity.type);\r\n this.appObjects.registerSingleton(this);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"HostEditingStateEntity.js","sourceRoot":"","sources":["../../../../src/StateMachine/Entities/HostEditingStateEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EACL,qBAAqB,EAErB,eAAe,EAEhB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAgB,sBAAuB,SAAQ,eAAe;IA2ClE,MAAM,CAAC,GAAG,CAAC,UAAyB;QAClC,OAAO,qBAAqB,CAC1B,sBAAsB,CAAC,IAAI,EAC3B,UAAU,CACX,CAAC;IACJ,CAAC;;AA/CM,2BAAI,GAAG,wBAAwB,CAAC;AAkDzC;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,SAAoB;IAEpB,OAAO,IAAI,yBAAyB,CAAC,SAAS,CAAC,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,yBAA0B,SAAQ,sBAAsB;IAK5D,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC;IAC1C,CAAC;IAGD,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAGD,IAAI,sBAAsB;QACxB,OAAO,IAAI,CAAC,uBAAuB,CAAC;IACtC,CAAC;IACD,IAAI,sBAAsB,CAAC,GAAuB;QAChD,IAAI,IAAI,CAAC,uBAAuB,KAAK,GAAG;YAAE,OAAO;QAEjD,IAAI,CAAC,uBAAuB,GAAG,GAAG,CAAC;QACnC,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAED;;;OAGG;IACH,IAAY,gBAAgB;QAC1B,OAAO,IAAI,CAAC,kBAAkB,CAAmB,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC1E,CAAC;IAUD,IAAI,mBAAmB;QACrB,OAAO,IAAI,CAAC,2BAA2B,CAAC,GAAG,CAAC;IAC9C,CAAC;IAoHD,YAAY,SAAoB;QAC9B,KAAK,CAAC,SAAS,EAAE,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAvJxC,gBAAW,GAAG,KAAK,CAAC;QAwB5B;;;WAGG;QACK,gCAA2B,GAAG,IAAI,eAAe,CACvD,KAAK,EACL,IAAI,CAAC,cAAc,CACpB,CAAC;QAKF;;;;WAIG;QACK,mBAAc,GAAG,GAAG,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,aAAa;gBAAE,OAAO,KAAK,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,iBAAiB;gBAAE,OAAO,IAAI,CAAC;YAEzC,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAC;YAEzE,IAAI,IAAI,CAAC,aAAa,CAAC,gBAAgB,KAAK,IAAI,CAAC,iBAAiB,CAAC,QAAQ;gBACzE,OAAO,IAAI,CAAC;YAEd,IACE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM;gBAEzE,OAAO,IAAI,CAAC;YACd,IAAI,iBAAiB,GAAG,KAAK,CAAC;YAC9B,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,cAAc,EAAE,CAAC,EAAE,EAAE;gBACtD,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC1D,IAAI,eAAe,KAAK,cAAc,EAAE,CAAC;oBACvC,iBAAiB,GAAG,IAAI,CAAC;gBAC3B,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,iBAAiB,EAAE,CAAC;gBACtB,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;YACvE,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,iBAAiB,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;YACxE,IAAI,iBAAiB,KAAK,YAAY;gBAAE,OAAO,IAAI,CAAC;YAEpD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEF;;;WAGG;QACK,wBAAmB,GAAG,GAAS,EAAE;YACvC,IAAI,CAAC,2BAA2B,CAAC,GAAG,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC/D,CAAC,CAAC;QAEF;;;WAGG;QACH,kBAAa,GAAG,GAAgC,EAAE;YAChD,IAAI,CAAC,IAAI,CAAC,gBAAgB;gBAAE,OAAO;YAEnC,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;YACnC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC;YAC5D,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAC/D,IAAI,CAAC,2BAA2B,CAAC,GAAG,GAAG,IAAI,CAAC;YAE5C,OAAO,IAAI,CAAC,aAAa,CAAC;QAC5B,CAAC,CAAC;QAEF;;;WAGG;QACH,iBAAY,GAAG,CAAC,KAAsB,EAAQ,EAAE;YAC9C,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;YAE3B,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YACxC,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAE/D,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,CAAC,CAAC;QAEF;;;;WAIG;QACH,oBAAe,GAAG,GAAS,EAAE;YAC3B,IAAI,CAAC,IAAI,CAAC,aAAa;gBAAE,OAAO;YAEhC,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC3B,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAC5D,CAAC;YAED,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC,CAAC;QAEF;;;WAGG;QACH,kBAAa,GAAG,GAAS,EAAE;YACzB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC,CAAC;QAEF;;;WAGG;QACK,uBAAkB,GAAG,GAAG,EAAE;YAChC,IAAI,CAAC,IAAI,CAAC,aAAa;gBAAE,OAAO;YAEhC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAClE,IAAI,CAAC,uBAAuB,GAAG,SAAS,CAAC;YACzC,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;YAC/B,IAAI,CAAC,2BAA2B,CAAC,GAAG,GAAG,KAAK,CAAC;YAC7C,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,CAAC,CAAC;QAIA,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;CACF","sourcesContent":["import { MemoizedBoolean } from \"@vived/core\";\r\nimport {\r\n getSingletonComponent,\r\n AppObject,\r\n AppObjectEntity,\r\n AppObjectRepo\r\n} from \"@vived/core\";\r\nimport { HostStateEntity, StateDTO } from \"./HostStateEntity\";\r\nimport { HostStateMachine } from \"./HostStateMachine\";\r\n\r\n/**\r\n * HostEditingStateEntity handles the editing workflow for state entities.\r\n *\r\n * This singleton component manages the process of creating new states or editing\r\n * existing states in the host state machine. It tracks changes made during editing,\r\n * maintains the original state for cancellation/rollback, and provides validation.\r\n *\r\n * The component implements a standard editing pattern:\r\n * 1. Start editing (startEditing) or create new (startNewState)\r\n * 2. Make changes to the editingState directly\r\n * 3. Complete with either finishEditing (commit) or cancelEditState (rollback)\r\n *\r\n * This entity is a critical part of the state authoring workflow and works closely\r\n * with HostStateMachine and HostStateEntity.\r\n */\r\nexport abstract class HostEditingStateEntity extends AppObjectEntity {\r\n static type = \"HostEditingStateEntity\";\r\n\r\n /** Whether currently in edit mode for a state */\r\n abstract get isEditing(): boolean;\r\n\r\n /** Whether editing a newly created state (true) or existing state (false) */\r\n abstract get isNewState(): boolean;\r\n\r\n /** The state entity currently being edited, if any */\r\n abstract get editingState(): HostStateEntity | undefined;\r\n\r\n /** Whether changes have been made since starting edit mode */\r\n abstract get somethingHasChanged(): boolean;\r\n\r\n /** Validation message if the current state is invalid, undefined if valid */\r\n abstract stateValidationMessage?: string;\r\n\r\n /**\r\n * Creates a new state entity and begins editing it\r\n * @returns The newly created state entity that's being edited\r\n */\r\n abstract startNewState(): HostStateEntity | undefined;\r\n\r\n /**\r\n * Begins editing an existing state entity\r\n * @param state The state entity to begin editing\r\n */\r\n abstract startEditing(state: HostStateEntity): void;\r\n\r\n /**\r\n * Cancels the current edit operation and reverts any changes\r\n * For new states, removes them from the state machine\r\n * For existing states, reverts to original values\r\n */\r\n abstract cancelEditState(): void;\r\n\r\n /**\r\n * Completes the current edit operation, keeping all changes\r\n * Performs no validation - validation should happen before calling this\r\n */\r\n abstract finishEditing(): void;\r\n\r\n static get(appObjects: AppObjectRepo) {\r\n return getSingletonComponent<HostEditingStateEntity>(\r\n HostEditingStateEntity.type,\r\n appObjects\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Factory function for creating a HostEditingStateEntity instance\r\n * @param appObject The AppObject to associate with this entity\r\n * @returns A new HostEditingStateEntity instance\r\n */\r\nexport function makeHostEditingStateEntity(\r\n appObject: AppObject\r\n): HostEditingStateEntity {\r\n return new HostEditingStateEntityImp(appObject);\r\n}\r\n\r\n/**\r\n * Implementation of the HostEditingStateEntity abstract class\r\n * Manages the state editing workflow and tracks changes\r\n */\r\nclass HostEditingStateEntityImp extends HostEditingStateEntity {\r\n /** Stores the original state data for reverting changes on cancel */\r\n private originalStateData?: StateDTO;\r\n\r\n private _editingState?: HostStateEntity;\r\n get editingState() {\r\n return this._editingState;\r\n }\r\n\r\n get isEditing(): boolean {\r\n return this._editingState !== undefined;\r\n }\r\n\r\n private _isNewState = false;\r\n get isNewState(): boolean {\r\n return this._isNewState;\r\n }\r\n\r\n private _stateValidationMessage?: string | undefined;\r\n get stateValidationMessage(): string | undefined {\r\n return this._stateValidationMessage;\r\n }\r\n set stateValidationMessage(val: string | undefined) {\r\n if (this._stateValidationMessage === val) return;\r\n\r\n this._stateValidationMessage = val;\r\n this.notifyOnChange();\r\n }\r\n\r\n /**\r\n * Reference to the HostStateMachine singleton\r\n * Used for creating and managing states\r\n */\r\n private get hostStateMachine() {\r\n return this.getCachedSingleton<HostStateMachine>(HostStateMachine.type);\r\n }\r\n\r\n /**\r\n * Tracks whether changes have been made to the state being edited\r\n * Uses a memoized value to efficiently notify observers only when value changes\r\n */\r\n private memoizedSomethingHasChanged = new MemoizedBoolean(\r\n false,\r\n this.notifyOnChange\r\n );\r\n get somethingHasChanged(): boolean {\r\n return this.memoizedSomethingHasChanged.val;\r\n }\r\n\r\n /**\r\n * Compares the current state with the original state to detect changes\r\n * Performs deep comparison of all relevant properties\r\n * @returns true if changes were detected, false otherwise\r\n */\r\n private checkForChange = () => {\r\n if (!this._editingState) return false;\r\n if (!this.originalStateData) return true;\r\n\r\n if (this._editingState.name !== this.originalStateData.name) return true;\r\n\r\n if (this._editingState.expectedResponse !== this.originalStateData.response)\r\n return true;\r\n\r\n if (\r\n this._editingState.assets.length !== this.originalStateData.assets.length\r\n )\r\n return true;\r\n let assetsHaveChanged = false;\r\n this._editingState.assets.forEach((currentAssetID, i) => {\r\n const originalAssetId = this.originalStateData!.assets[i];\r\n if (originalAssetId !== currentAssetID) {\r\n assetsHaveChanged = true;\r\n }\r\n });\r\n\r\n if (assetsHaveChanged) {\r\n return true;\r\n }\r\n\r\n const currentDataString = JSON.stringify(this._editingState.stateData);\r\n const originalData = JSON.stringify(this.originalStateData?.data ?? \"\");\r\n if (currentDataString !== originalData) return true;\r\n\r\n return false;\r\n };\r\n\r\n /**\r\n * Observer callback for state changes\r\n * Updates the somethingHasChanged flag when the state being edited changes\r\n */\r\n private onStateEntityChange = (): void => {\r\n this.memoizedSomethingHasChanged.val = this.checkForChange();\r\n };\r\n\r\n /**\r\n * Creates a new state and begins editing it\r\n * @returns The newly created state entity or undefined if creation failed\r\n */\r\n startNewState = (): HostStateEntity | undefined => {\r\n if (!this.hostStateMachine) return;\r\n\r\n this.originalStateData = undefined;\r\n this._isNewState = true;\r\n this._editingState = this.hostStateMachine.createNewState();\r\n this._editingState.addChangeObserver(this.onStateEntityChange);\r\n this.memoizedSomethingHasChanged.val = true;\r\n\r\n return this._editingState;\r\n };\r\n\r\n /**\r\n * Begins editing an existing state\r\n * @param state The state entity to edit\r\n */\r\n startEditing = (state: HostStateEntity): void => {\r\n this._editingState = state;\r\n\r\n this.originalStateData = state.getDTO();\r\n this._editingState.addChangeObserver(this.onStateEntityChange);\r\n\r\n this.notifyOnChange();\r\n };\r\n\r\n /**\r\n * Cancels editing and reverts changes\r\n * For new states, removes them from the state machine\r\n * For existing states, restores the original values\r\n */\r\n cancelEditState = (): void => {\r\n if (!this._editingState) return;\r\n\r\n if (this.originalStateData) {\r\n this._editingState.setDTO(this.originalStateData);\r\n } else {\r\n this.hostStateMachine?.deleteState(this._editingState.id);\r\n }\r\n\r\n this.resetInternalState();\r\n };\r\n\r\n /**\r\n * Completes editing, keeping all changes\r\n * Simply cleans up the internal state without reverting changes\r\n */\r\n finishEditing = (): void => {\r\n this.resetInternalState();\r\n };\r\n\r\n /**\r\n * Resets the internal state after editing is complete\r\n * Cleans up observers and notifies clients of the change\r\n */\r\n private resetInternalState = () => {\r\n if (!this._editingState) return;\r\n\r\n this._isNewState = false;\r\n this._editingState.removeChangeObserver(this.onStateEntityChange);\r\n this._stateValidationMessage = undefined;\r\n this._editingState = undefined;\r\n this.memoizedSomethingHasChanged.val = false;\r\n this.notifyOnChange();\r\n };\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, HostEditingStateEntity.type);\r\n this.appObjects.registerSingleton(this);\r\n }\r\n}\r\n"]}
@@ -1,5 +1,9 @@
1
1
  import { MemoizedString } from "@vived/core";
2
2
  import { AppObjectEntity } from "@vived/core";
3
+ /**
4
+ * Defines the types of challenge responses that can be expected in a state
5
+ * These represent different feedback mechanisms available to the user
6
+ */
3
7
  export var ChallengeResponse;
4
8
  (function (ChallengeResponse) {
5
9
  ChallengeResponse["NONE"] = "NONE";
@@ -7,19 +11,63 @@ export var ChallengeResponse;
7
11
  ChallengeResponse["HIT"] = "HIT";
8
12
  ChallengeResponse["MULTIHIT"] = "MULTIHIT";
9
13
  ChallengeResponse["PROGRESS"] = "PROGRESS";
10
- ChallengeResponse["QUALITY"] = "QUALITY";
14
+ ChallengeResponse["QUALITY"] = "QUALITY"; // Quality-rated response
11
15
  })(ChallengeResponse || (ChallengeResponse = {}));
16
+ /**
17
+ * Defines the loading states for streaming assets in a state
18
+ */
19
+ export var StreamState;
20
+ (function (StreamState) {
21
+ StreamState["INIT"] = "INIT";
22
+ StreamState["LOADING"] = "LOADING";
23
+ StreamState["READY"] = "READY";
24
+ StreamState["ERROR"] = "ERROR"; // Error occurred during loading
25
+ })(StreamState || (StreamState = {}));
26
+ /**
27
+ * HostStateEntity represents a single state within a state machine.
28
+ *
29
+ * Each state contains:
30
+ * - Metadata (name, ID)
31
+ * - References to assets needed by the state
32
+ * - Custom state data specific to the app implementation
33
+ * - Expected response type for challenge/interaction
34
+ *
35
+ * States are managed by the HostStateMachine and can be persisted/restored
36
+ * through the DTO pattern.
37
+ *
38
+ * This is a core component of the VIVED platform's state-based application model,
39
+ * allowing apps to define discrete states with specific content and behaviors.
40
+ */
12
41
  export class HostStateEntity extends AppObjectEntity {
42
+ /**
43
+ * Gets an existing HostStateEntity by ID
44
+ * @param id The unique identifier for the state
45
+ * @param appObjects The app object repository
46
+ * @returns The state entity if found, undefined otherwise
47
+ */
13
48
  static get(id, appObjects) {
14
49
  const ao = appObjects.get(id);
15
50
  return ao?.getComponent(HostStateEntity.type);
16
51
  }
17
52
  }
18
53
  HostStateEntity.type = "HostStateEntity";
54
+ /**
55
+ * Factory function for creating a HostStateEntity instance
56
+ * @param appObject The AppObject to associate with this entity
57
+ * @returns A new HostStateEntity instance
58
+ */
19
59
  export function makeHostStateEntity(appObject) {
20
60
  return new HostStateEntityImp(appObject);
21
61
  }
62
+ /**
63
+ * Implementation of the HostStateEntity abstract class
64
+ * Provides concrete implementation of state properties and methods
65
+ */
22
66
  class HostStateEntityImp extends HostStateEntity {
67
+ /**
68
+ * The unique identifier for this state
69
+ * Derived from the associated AppObject ID
70
+ */
23
71
  get id() {
24
72
  return this.appObject.id;
25
73
  }
@@ -32,6 +80,11 @@ class HostStateEntityImp extends HostStateEntity {
32
80
  get stateData() {
33
81
  return this._data;
34
82
  }
83
+ /**
84
+ * Updates the state data, optionally checking if it actually changed
85
+ * @param val New state data
86
+ * @param checkForChange If true, only notifies on actual changes
87
+ */
35
88
  setStateData(val, checkForChange) {
36
89
  let notify = true;
37
90
  if (checkForChange) {
@@ -77,6 +130,10 @@ class HostStateEntityImp extends HostStateEntity {
77
130
  this._expectedResponse = val;
78
131
  this.notifyOnChange();
79
132
  }
133
+ /**
134
+ * Serializes state to a data transfer object
135
+ * Used for persistence and state management
136
+ */
80
137
  getDTO() {
81
138
  return {
82
139
  id: this.id,
@@ -87,6 +144,11 @@ class HostStateEntityImp extends HostStateEntity {
87
144
  appID: this.appID
88
145
  };
89
146
  }
147
+ /**
148
+ * Applies state data from a DTO
149
+ * Used when restoring state or rolling back changes
150
+ * @param dto The data transfer object to apply
151
+ */
90
152
  setDTO(dto) {
91
153
  if (dto.id !== this.id) {
92
154
  this.warn("DTO id does not match my ID. Skipping");
@@ -109,12 +171,39 @@ class HostStateEntityImp extends HostStateEntity {
109
171
  set appID(val) {
110
172
  this.memoisedAppID.val = val;
111
173
  }
174
+ get streamState() {
175
+ return this.memoizedStreamState.val;
176
+ }
177
+ set streamState(val) {
178
+ this.memoizedStreamState.val = val;
179
+ }
112
180
  constructor(appObject) {
113
181
  super(appObject, HostStateEntity.type);
182
+ /**
183
+ * Memoized name property with change notification
184
+ * Uses MemoizedString to efficiently track changes
185
+ */
114
186
  this.memoizedName = new MemoizedString("", this.notifyOnChange);
187
+ /**
188
+ * Custom state data object
189
+ * This is app-specific data that defines the state behavior
190
+ */
115
191
  this._data = {};
192
+ /**
193
+ * Array of asset IDs required by this state
194
+ * Assets are loaded before the state becomes active
195
+ */
116
196
  this._assets = [];
197
+ /**
198
+ * ID of the app this state belongs to
199
+ * States can only be used with their associated app
200
+ */
117
201
  this.memoisedAppID = new MemoizedString("", this.notifyOnChange);
202
+ /**
203
+ * Current loading state for streaming assets
204
+ * Used to track progress when loading assets for this state
205
+ */
206
+ this.memoizedStreamState = new MemoizedString(StreamState.INIT, this.notifyOnChange);
118
207
  }
119
208
  }
120
209
  //# sourceMappingURL=HostStateEntity.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"HostStateEntity.js","sourceRoot":"","sources":["../../../../src/StateMachine/Entities/HostStateEntity.ts"],"names":[],"mappings":"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","sourcesContent":["import { MemoizedString } from \"@vived/core\";\r\nimport { AppObject, AppObjectEntity, AppObjectRepo } from \"@vived/core\";\r\n\r\nexport enum ChallengeResponse {\r\n NONE = \"NONE\",\r\n SCORE = \"SCORE\",\r\n HIT = \"HIT\",\r\n MULTIHIT = \"MULTIHIT\",\r\n PROGRESS = \"PROGRESS\",\r\n QUALITY = \"QUALITY\"\r\n}\r\n\r\nexport interface StateDTO {\r\n id: string;\r\n name: string;\r\n data: object;\r\n assets: string[];\r\n response: string | undefined;\r\n appID: string;\r\n}\r\n\r\nexport abstract class HostStateEntity extends AppObjectEntity {\r\n static type = \"HostStateEntity\";\r\n\r\n abstract get id(): string;\r\n\r\n abstract name: string;\r\n abstract assets: string[];\r\n abstract expectedResponse: ChallengeResponse | undefined;\r\n abstract appID: string;\r\n abstract getDTO(): StateDTO;\r\n abstract setDTO(dto: StateDTO): void;\r\n\r\n abstract get stateData(): object;\r\n abstract setStateData(val: object, checkForChange?: boolean): void;\r\n\r\n static get(id: string, appObjects: AppObjectRepo) {\r\n const ao = appObjects.get(id);\r\n return ao?.getComponent<HostStateEntity>(HostStateEntity.type);\r\n }\r\n}\r\n\r\nexport function makeHostStateEntity(appObject: AppObject): HostStateEntity {\r\n return new HostStateEntityImp(appObject);\r\n}\r\n\r\nclass HostStateEntityImp extends HostStateEntity {\r\n get id(): string {\r\n return this.appObject.id;\r\n }\r\n\r\n private memoizedName = new MemoizedString(\"\", this.notifyOnChange);\r\n get name(): string {\r\n return this.memoizedName.val;\r\n }\r\n set name(val: string) {\r\n this.memoizedName.val = val;\r\n }\r\n\r\n private _data = {};\r\n get stateData(): object {\r\n return this._data;\r\n }\r\n\r\n setStateData(val: object, checkForChange?: boolean): void {\r\n let notify = true;\r\n if (checkForChange) {\r\n const currentData = JSON.stringify(this._data);\r\n const newData = JSON.stringify(val);\r\n\r\n if (currentData === newData) {\r\n notify = false;\r\n }\r\n }\r\n\r\n this._data = val;\r\n if (notify) {\r\n this.notifyOnChange();\r\n }\r\n }\r\n\r\n private _assets: string[] = [];\r\n get assets() {\r\n return [...this._assets];\r\n }\r\n set assets(val: string[]) {\r\n if (val.length !== this._assets.length) {\r\n this._assets = val;\r\n this.notifyOnChange();\r\n return;\r\n }\r\n\r\n let somethingHasChanged = false;\r\n val.forEach((newAsset, i) => {\r\n const existingAsset = this._assets[i];\r\n if (existingAsset !== newAsset) {\r\n somethingHasChanged = true;\r\n }\r\n });\r\n\r\n if (!somethingHasChanged) {\r\n return;\r\n }\r\n\r\n this._assets = val;\r\n this.notifyOnChange();\r\n }\r\n\r\n private _expectedResponse: ChallengeResponse | undefined;\r\n get expectedResponse() {\r\n return this._expectedResponse;\r\n }\r\n set expectedResponse(val: ChallengeResponse | undefined) {\r\n if (val === this._expectedResponse) return;\r\n\r\n this._expectedResponse = val;\r\n this.notifyOnChange();\r\n }\r\n\r\n getDTO(): StateDTO {\r\n return {\r\n id: this.id,\r\n assets: [...this._assets],\r\n data: this._data,\r\n name: this.memoizedName.val,\r\n response: this._expectedResponse,\r\n appID: this.appID\r\n };\r\n }\r\n\r\n setDTO(dto: StateDTO): void {\r\n if (dto.id !== this.id) {\r\n this.warn(\"DTO id does not match my ID. Skipping\");\r\n return;\r\n }\r\n\r\n this.setStateData(dto.data, true);\r\n this.assets = [...dto.assets];\r\n this.memoizedName.val = dto.name;\r\n this.memoisedAppID.val = dto.appID;\r\n\r\n if ((Object as any).values(ChallengeResponse).includes(dto.response)) {\r\n this.expectedResponse = dto.response as ChallengeResponse;\r\n } else {\r\n this.expectedResponse = undefined;\r\n }\r\n }\r\n\r\n private memoisedAppID = new MemoizedString(\"\", this.notifyOnChange);\r\n get appID(): string {\r\n return this.memoisedAppID.val;\r\n }\r\n set appID(val: string) {\r\n this.memoisedAppID.val = val;\r\n }\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, HostStateEntity.type);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"HostStateEntity.js","sourceRoot":"","sources":["../../../../src/StateMachine/Entities/HostStateEntity.ts"],"names":[],"mappings":"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","sourcesContent":["import { MemoizedString } from \"@vived/core\";\r\nimport { AppObject, AppObjectEntity, AppObjectRepo } from \"@vived/core\";\r\n\r\n/**\r\n * Defines the types of challenge responses that can be expected in a state\r\n * These represent different feedback mechanisms available to the user\r\n */\r\nexport enum ChallengeResponse {\r\n NONE = \"NONE\", // No specific response expected\r\n SCORE = \"SCORE\", // Numeric score-based response\r\n HIT = \"HIT\", // Binary hit/miss response\r\n MULTIHIT = \"MULTIHIT\", // Multiple hit targets response\r\n PROGRESS = \"PROGRESS\", // Continuous progress response\r\n QUALITY = \"QUALITY\" // Quality-rated response\r\n}\r\n\r\n/**\r\n * Defines the loading states for streaming assets in a state\r\n */\r\nexport enum StreamState {\r\n INIT = \"INIT\", // Initial state before loading\r\n LOADING = \"LOADING\", // Assets are currently loading\r\n READY = \"READY\", // Assets have loaded successfully\r\n ERROR = \"ERROR\" // Error occurred during loading\r\n}\r\n\r\n/**\r\n * Data Transfer Object for serializing/deserializing state data\r\n * Used for persistence, state management, and undo/redo operations\r\n */\r\nexport interface StateDTO {\r\n id: string; // Unique identifier for the state\r\n name: string; // Display name for the state\r\n data: object; // Custom state data - structure depends on app implementation\r\n assets: string[]; // Array of asset IDs referenced by this state\r\n response: string | undefined; // Expected challenge response type\r\n appID: string; // ID of the app this state belongs to\r\n}\r\n\r\n/**\r\n * HostStateEntity represents a single state within a state machine.\r\n *\r\n * Each state contains:\r\n * - Metadata (name, ID)\r\n * - References to assets needed by the state\r\n * - Custom state data specific to the app implementation\r\n * - Expected response type for challenge/interaction\r\n *\r\n * States are managed by the HostStateMachine and can be persisted/restored\r\n * through the DTO pattern.\r\n *\r\n * This is a core component of the VIVED platform's state-based application model,\r\n * allowing apps to define discrete states with specific content and behaviors.\r\n */\r\nexport abstract class HostStateEntity extends AppObjectEntity {\r\n static type = \"HostStateEntity\";\r\n\r\n /** Unique identifier for this state */\r\n abstract get id(): string;\r\n\r\n /** Human-readable name of the state */\r\n abstract name: string;\r\n\r\n /** List of asset IDs required by this state */\r\n abstract assets: string[];\r\n\r\n /** Type of response expected from user interactions in this state */\r\n abstract expectedResponse: ChallengeResponse | undefined;\r\n\r\n /** ID of the app this state belongs to */\r\n abstract appID: string;\r\n\r\n /** Current loading state for streaming assets */\r\n abstract streamState: StreamState;\r\n\r\n /**\r\n * Serializes the state to a plain object for persistence\r\n * @returns StateDTO containing all state data\r\n */\r\n abstract getDTO(): StateDTO;\r\n\r\n /**\r\n * Deserializes from a DTO and updates this state's properties\r\n * @param dto The state data transfer object to apply\r\n */\r\n abstract setDTO(dto: StateDTO): void;\r\n\r\n /**\r\n * Gets the custom state data object\r\n * Structure is specific to the app implementation\r\n */\r\n abstract get stateData(): object;\r\n\r\n /**\r\n * Updates the custom state data object\r\n * @param val New state data object\r\n * @param checkForChange If true, only notifies observers when actual changes occur\r\n */\r\n abstract setStateData(val: object, checkForChange?: boolean): void;\r\n\r\n /**\r\n * Gets an existing HostStateEntity by ID\r\n * @param id The unique identifier for the state\r\n * @param appObjects The app object repository\r\n * @returns The state entity if found, undefined otherwise\r\n */\r\n static get(id: string, appObjects: AppObjectRepo) {\r\n const ao = appObjects.get(id);\r\n return ao?.getComponent<HostStateEntity>(HostStateEntity.type);\r\n }\r\n}\r\n\r\n/**\r\n * Factory function for creating a HostStateEntity instance\r\n * @param appObject The AppObject to associate with this entity\r\n * @returns A new HostStateEntity instance\r\n */\r\nexport function makeHostStateEntity(appObject: AppObject): HostStateEntity {\r\n return new HostStateEntityImp(appObject);\r\n}\r\n\r\n/**\r\n * Implementation of the HostStateEntity abstract class\r\n * Provides concrete implementation of state properties and methods\r\n */\r\nclass HostStateEntityImp extends HostStateEntity {\r\n /**\r\n * The unique identifier for this state\r\n * Derived from the associated AppObject ID\r\n */\r\n get id(): string {\r\n return this.appObject.id;\r\n }\r\n\r\n /**\r\n * Memoized name property with change notification\r\n * Uses MemoizedString to efficiently track changes\r\n */\r\n private memoizedName = new MemoizedString(\"\", this.notifyOnChange);\r\n get name(): string {\r\n return this.memoizedName.val;\r\n }\r\n set name(val: string) {\r\n this.memoizedName.val = val;\r\n }\r\n\r\n /**\r\n * Custom state data object\r\n * This is app-specific data that defines the state behavior\r\n */\r\n private _data = {};\r\n get stateData(): object {\r\n return this._data;\r\n }\r\n\r\n /**\r\n * Updates the state data, optionally checking if it actually changed\r\n * @param val New state data\r\n * @param checkForChange If true, only notifies on actual changes\r\n */\r\n setStateData(val: object, checkForChange?: boolean): void {\r\n let notify = true;\r\n if (checkForChange) {\r\n const currentData = JSON.stringify(this._data);\r\n const newData = JSON.stringify(val);\r\n\r\n if (currentData === newData) {\r\n notify = false;\r\n }\r\n }\r\n\r\n this._data = val;\r\n if (notify) {\r\n this.notifyOnChange();\r\n }\r\n }\r\n\r\n /**\r\n * Array of asset IDs required by this state\r\n * Assets are loaded before the state becomes active\r\n */\r\n private _assets: string[] = [];\r\n get assets() {\r\n return [...this._assets];\r\n }\r\n set assets(val: string[]) {\r\n if (val.length !== this._assets.length) {\r\n this._assets = val;\r\n this.notifyOnChange();\r\n return;\r\n }\r\n\r\n let somethingHasChanged = false;\r\n val.forEach((newAsset, i) => {\r\n const existingAsset = this._assets[i];\r\n if (existingAsset !== newAsset) {\r\n somethingHasChanged = true;\r\n }\r\n });\r\n\r\n if (!somethingHasChanged) {\r\n return;\r\n }\r\n\r\n this._assets = val;\r\n this.notifyOnChange();\r\n }\r\n\r\n /**\r\n * Type of response expected from user interactions\r\n * Determines how challenge results are processed\r\n */\r\n private _expectedResponse: ChallengeResponse | undefined;\r\n get expectedResponse() {\r\n return this._expectedResponse;\r\n }\r\n set expectedResponse(val: ChallengeResponse | undefined) {\r\n if (val === this._expectedResponse) return;\r\n\r\n this._expectedResponse = val;\r\n this.notifyOnChange();\r\n }\r\n\r\n /**\r\n * Serializes state to a data transfer object\r\n * Used for persistence and state management\r\n */\r\n getDTO(): StateDTO {\r\n return {\r\n id: this.id,\r\n assets: [...this._assets],\r\n data: this._data,\r\n name: this.memoizedName.val,\r\n response: this._expectedResponse,\r\n appID: this.appID\r\n };\r\n }\r\n\r\n /**\r\n * Applies state data from a DTO\r\n * Used when restoring state or rolling back changes\r\n * @param dto The data transfer object to apply\r\n */\r\n setDTO(dto: StateDTO): void {\r\n if (dto.id !== this.id) {\r\n this.warn(\"DTO id does not match my ID. Skipping\");\r\n return;\r\n }\r\n\r\n this.setStateData(dto.data, true);\r\n this.assets = [...dto.assets];\r\n this.memoizedName.val = dto.name;\r\n this.memoisedAppID.val = dto.appID;\r\n\r\n if ((Object as any).values(ChallengeResponse).includes(dto.response)) {\r\n this.expectedResponse = dto.response as ChallengeResponse;\r\n } else {\r\n this.expectedResponse = undefined;\r\n }\r\n }\r\n\r\n /**\r\n * ID of the app this state belongs to\r\n * States can only be used with their associated app\r\n */\r\n private memoisedAppID = new MemoizedString(\"\", this.notifyOnChange);\r\n get appID(): string {\r\n return this.memoisedAppID.val;\r\n }\r\n set appID(val: string) {\r\n this.memoisedAppID.val = val;\r\n }\r\n\r\n /**\r\n * Current loading state for streaming assets\r\n * Used to track progress when loading assets for this state\r\n */\r\n private memoizedStreamState = new MemoizedString(\r\n StreamState.INIT,\r\n this.notifyOnChange\r\n );\r\n get streamState(): StreamState {\r\n return this.memoizedStreamState.val as StreamState;\r\n }\r\n set streamState(val: StreamState) {\r\n this.memoizedStreamState.val = val;\r\n }\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, HostStateEntity.type);\r\n }\r\n}\r\n"]}
@@ -1,25 +1,68 @@
1
1
  import { generateUniqueID, MemoizedBoolean } from "@vived/core";
2
2
  import { getSingletonComponent, AppObjectEntity } from "@vived/core";
3
3
  import { makeHostStateEntity } from "./HostStateEntity";
4
+ /**
5
+ * HostStateMachine manages a collection of states and controls state transitions.
6
+ *
7
+ * This singleton component serves as the central controller for the VIVED platform's
8
+ * state-based application model. It maintains an ordered collection of states,
9
+ * tracks the currently active state, and provides methods for state transitions,
10
+ * creation, deletion, and reordering.
11
+ *
12
+ * The state machine can be used in both runtime and authoring modes:
13
+ * - In runtime: For navigating between predefined states in an application
14
+ * - In authoring: For creating and organizing states through a content editor
15
+ *
16
+ * This entity works closely with HostStateEntity (individual states) and
17
+ * HostEditingStateEntity (for state authoring).
18
+ */
4
19
  export class HostStateMachine extends AppObjectEntity {
20
+ /**
21
+ * Gets the singleton instance of HostStateMachine
22
+ * @param appObjects The app object repository
23
+ * @returns The HostStateMachine instance
24
+ */
5
25
  static get(appObjects) {
6
26
  return getSingletonComponent(HostStateMachine.type, appObjects);
7
27
  }
8
28
  }
9
29
  HostStateMachine.type = "HostStateMachine";
30
+ /**
31
+ * Factory function for creating a HostStateMachine instance
32
+ * @param appObject The AppObject to associate with this entity
33
+ * @returns A new HostStateMachine instance
34
+ */
10
35
  export function makeHostStateMachine(appObject) {
11
36
  return new HostStateMachineImp(appObject);
12
37
  }
38
+ /**
39
+ * Implementation of the HostStateMachine abstract class
40
+ * Provides concrete implementation of state machine functionality
41
+ */
13
42
  class HostStateMachineImp extends HostStateMachine {
43
+ /**
44
+ * List of all state IDs in order
45
+ * @returns Array of state IDs
46
+ */
14
47
  get states() {
15
48
  return this._states.map((state) => state.id);
16
49
  }
50
+ /**
51
+ * Total number of states in the machine
52
+ * @returns Number of states
53
+ */
17
54
  get stateCount() {
18
55
  return this._states.length;
19
56
  }
20
57
  get activeState() {
21
58
  return this._activeState;
22
59
  }
60
+ /**
61
+ * ID of the state preceding the active state
62
+ * Returns undefined if:
63
+ * - No active state
64
+ * - Active state is the first state
65
+ */
23
66
  get previousState() {
24
67
  if (!this._activeState)
25
68
  return undefined;
@@ -28,6 +71,12 @@ class HostStateMachineImp extends HostStateMachine {
28
71
  return undefined;
29
72
  return this._states[currentIndex - 1].id;
30
73
  }
74
+ /**
75
+ * ID of the state following the active state
76
+ * Returns undefined if:
77
+ * - No active state
78
+ * - Active state is the last state
79
+ */
31
80
  get nextState() {
32
81
  if (!this._activeState)
33
82
  return undefined;
@@ -63,6 +112,11 @@ class HostStateMachineImp extends HostStateMachine {
63
112
  set lastAssets(lastAssets) {
64
113
  this._lastAssets = lastAssets;
65
114
  }
115
+ /**
116
+ * Helper method to find a state by ID
117
+ * @param id ID to search for
118
+ * @returns The state entity or undefined if not found
119
+ */
66
120
  findStateByID(id) {
67
121
  for (const state of this._states) {
68
122
  if (state.id === id) {
@@ -73,10 +127,25 @@ class HostStateMachineImp extends HostStateMachine {
73
127
  }
74
128
  constructor(appObject) {
75
129
  super(appObject, HostStateMachine.type);
130
+ /** Internal storage for state entities */
76
131
  this._states = [];
132
+ /** Duration for transitions between states (in seconds) */
77
133
  this.transitionDuration = 1;
134
+ /**
135
+ * Whether the state machine is in authoring mode
136
+ * In authoring mode, additional editing features are enabled
137
+ */
78
138
  this.memoizedIsAuthoring = new MemoizedBoolean(false, this.notifyOnChange);
139
+ /**
140
+ * Tracks assets used in previous state for preloading optimization
141
+ * Helps optimize asset loading between state transitions
142
+ */
79
143
  this._lastAssets = [];
144
+ /**
145
+ * Checks if a state with the given ID exists
146
+ * @param id ID to check
147
+ * @returns true if state exists, false otherwise
148
+ */
80
149
  this.hasState = (id) => {
81
150
  const state = this.findStateByID(id);
82
151
  if (state) {
@@ -86,6 +155,10 @@ class HostStateMachineImp extends HostStateMachine {
86
155
  return false;
87
156
  }
88
157
  };
158
+ /**
159
+ * Sets the active state by its ID
160
+ * @param id ID of the state to activate
161
+ */
89
162
  this.setActiveStateByID = (id) => {
90
163
  const state = this.findStateByID(id);
91
164
  if (!state)
@@ -95,35 +168,66 @@ class HostStateMachineImp extends HostStateMachine {
95
168
  this._activeState = state.id;
96
169
  this.notifyOnChange();
97
170
  };
171
+ /**
172
+ * Sets the active state by its index in the states array
173
+ * @param index Zero-based index of the state to activate
174
+ */
98
175
  this.setActiveStateByIndex = (index) => {
99
176
  if (index < 0 || index >= this._states.length)
100
177
  return;
101
178
  const state = this._states[index];
102
179
  this.setActiveStateByID(state.id);
103
180
  };
181
+ /**
182
+ * Clears the active state (no state will be active)
183
+ */
104
184
  this.clearActiveState = () => {
105
185
  if (!this.activeState)
106
186
  return;
107
187
  this._activeState = undefined;
108
188
  this.notifyOnChange();
109
189
  };
190
+ /**
191
+ * Replaces all states with a new collection
192
+ * @param states Array of state entities to use
193
+ */
110
194
  this.setStates = (states) => {
111
195
  this._states = states;
112
196
  this.notifyOnChange();
113
197
  };
198
+ /**
199
+ * Factory function for creating state entities
200
+ * Creates a new AppObject with the given ID and wraps it in a HostStateEntity
201
+ * @param id ID for the new state
202
+ * @returns A new HostStateEntity instance
203
+ */
114
204
  this.stateFactory = (id) => {
115
205
  const ao = this.appObjects.getOrCreate(id);
116
206
  return makeHostStateEntity(ao);
117
207
  };
208
+ /**
209
+ * Creates a new empty state and adds it to the end of the states array
210
+ * @returns The newly created state entity
211
+ */
118
212
  this.createNewState = () => {
119
213
  const newState = this.stateFactory(generateUniqueID());
120
214
  this._states.push(newState);
121
215
  this.notifyOnChange();
122
216
  return newState;
123
217
  };
218
+ /**
219
+ * Gets a state entity by its ID
220
+ * @param id ID of the state to retrieve
221
+ * @returns The state entity or undefined if not found
222
+ */
124
223
  this.getStateByID = (id) => {
125
224
  return this.findStateByID(id);
126
225
  };
226
+ /**
227
+ * Deletes a state from the machine by its ID
228
+ * Also disposes the associated AppObject
229
+ * @param id ID of the state to delete
230
+ */
127
231
  this.deleteState = (id) => {
128
232
  const index = this.getStateIndex(id);
129
233
  if (index === undefined) {
@@ -134,6 +238,10 @@ class HostStateMachineImp extends HostStateMachine {
134
238
  this._states.splice(index, 1);
135
239
  this.notifyOnChange();
136
240
  };
241
+ /**
242
+ * Deletes all states from the machine
243
+ * Also disposes all associated AppObjects
244
+ */
137
245
  this.deleteAllStates = () => {
138
246
  if (this._states.length === 0)
139
247
  return;
@@ -145,6 +253,11 @@ class HostStateMachineImp extends HostStateMachine {
145
253
  this.clearActiveState();
146
254
  this.notifyOnChange();
147
255
  };
256
+ /**
257
+ * Gets the index of a state in the states array
258
+ * @param id ID of the state
259
+ * @returns Zero-based index or undefined if not found
260
+ */
148
261
  this.getStateIndex = (id) => {
149
262
  let index = -1;
150
263
  this._states.forEach((state, i) => {
@@ -159,16 +272,30 @@ class HostStateMachineImp extends HostStateMachine {
159
272
  return undefined;
160
273
  }
161
274
  };
275
+ /**
276
+ * Activates the state before the current active state
277
+ * Does nothing if there is no previous state
278
+ */
162
279
  this.setPreviousStateActive = () => {
163
280
  if (!this.previousState)
164
281
  return;
165
282
  this.setActiveStateByID(this.previousState);
166
283
  };
284
+ /**
285
+ * Activates the state after the current active state
286
+ * Does nothing if there is no next state
287
+ */
167
288
  this.setNextStateActive = () => {
168
289
  if (!this.nextState)
169
290
  return;
170
291
  this.setActiveStateByID(this.nextState);
171
292
  };
293
+ /**
294
+ * Moves a state to a different position in the states array
295
+ * Used for reordering states in the state machine
296
+ * @param stateID ID of the state to move
297
+ * @param index Destination index
298
+ */
172
299
  this.setStateIndex = (stateID, index) => {
173
300
  // Check if the state exists
174
301
  const state = this.getStateByID(stateID);