http-request-manager 18.15.33 → 18.15.34

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 (300) hide show
  1. package/TEST_COVERAGE_SUMMARY.md +458 -0
  2. package/ng-package.json +8 -0
  3. package/package.json +4 -13
  4. package/src/docs/ADVANCED_WEBSOCKET.md +633 -0
  5. package/src/docs/ARCHITECTURE.md +633 -0
  6. package/src/docs/BATCH_REQUEST_README.md +467 -0
  7. package/src/docs/COMPLETE_API_REFERENCE.md +1037 -0
  8. package/src/docs/DATABASE_README.md +1195 -0
  9. package/src/docs/ENCRYPTION_README.md +403 -0
  10. package/src/docs/HTTP_MANAGER_README.md +628 -0
  11. package/src/docs/HTTP_SINGNALS_MANAGER_README.md +654 -0
  12. package/src/docs/HTTP_STATE_MANAGER_README.md +1391 -0
  13. package/src/docs/INTERCEPTOR_README.md +549 -0
  14. package/src/docs/LOCAL_STORAGE_README.md +1056 -0
  15. package/src/docs/LOCAL_STORAGE_SIGNALS_README.md +338 -0
  16. package/src/docs/LOGGER_README.md +310 -0
  17. package/src/docs/MESSAGE_TRACKER_README.md +518 -0
  18. package/src/docs/MESSAGE_TRACKER_SIGNALS_README.md +563 -0
  19. package/src/docs/MODELS_README.md +1264 -0
  20. package/src/docs/SIGNAL_SERVICES_README.md +238 -0
  21. package/src/docs/SQL_DIXIE_README.md +574 -0
  22. package/src/docs/STORE_STATE_MANAGER_README.md +556 -0
  23. package/src/docs/STORE_STATE_SIGNALS_README.md +600 -0
  24. package/src/docs/UPLOAD_REQUEST_README.md +324 -0
  25. package/src/docs/UTILS_README.md +1604 -0
  26. package/src/docs/WEBSOCKET_MESSAGE_SERVICE.md +799 -0
  27. package/src/docs/WEBSOCKET_SIGNALS_README.md +641 -0
  28. package/src/docs/WEBSOCKET_SINGLETON_REFACTORING.md +201 -0
  29. package/src/docs/WS_MANAGER_README.md +613 -0
  30. package/src/lib/http-request-manager.module.ts +147 -0
  31. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.html +116 -0
  32. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.scss +0 -0
  33. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.ts +255 -0
  34. package/src/lib/http-request-services-demo/http-request-services-demo.component.html +123 -0
  35. package/src/lib/http-request-services-demo/http-request-services-demo.component.scss +6 -0
  36. package/src/lib/http-request-services-demo/http-request-services-demo.component.ts +53 -0
  37. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.html +195 -0
  38. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.scss +17 -0
  39. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.ts +208 -0
  40. package/src/lib/http-request-services-demo/local-storage-signals-demo/local-storage-signals-demo.component.html +200 -0
  41. package/src/lib/http-request-services-demo/local-storage-signals-demo/local-storage-signals-demo.component.scss +17 -0
  42. package/src/lib/http-request-services-demo/local-storage-signals-demo/local-storage-signals-demo.component.ts +214 -0
  43. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/download-file/download-file.component.html +53 -0
  44. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/download-file/download-file.component.scss +60 -0
  45. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/download-file/download-file.component.ts +72 -0
  46. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/file-download.module.ts +28 -0
  47. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/file-downloader.component.html +10 -0
  48. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/file-downloader.component.scss +29 -0
  49. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/file-downloader.component.ts +100 -0
  50. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/models/download-labels-model.ts +22 -0
  51. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/spinner/spinner.component.html +8 -0
  52. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/spinner/spinner.component.scss +19 -0
  53. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/spinner/spinner.component.ts +26 -0
  54. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/app-session.model.ts +30 -0
  55. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/app.model.ts +19 -0
  56. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/get-sample.model.ts +25 -0
  57. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-ai-prompt.ts +19 -0
  58. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-client-details.ts +24 -0
  59. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-client-info.ts +30 -0
  60. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-client.model.ts +49 -0
  61. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-mapper-client-info.ts +33 -0
  62. package/src/lib/http-request-services-demo/request-manager-basic-demo/request-manager-basic-demo.component.html +279 -0
  63. package/src/lib/http-request-services-demo/request-manager-basic-demo/request-manager-basic-demo.component.scss +24 -0
  64. package/src/lib/http-request-services-demo/request-manager-basic-demo/request-manager-basic-demo.component.ts +461 -0
  65. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.html +53 -0
  66. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.scss +60 -0
  67. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.ts +72 -0
  68. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-download.module.ts +28 -0
  69. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.html +10 -0
  70. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.scss +29 -0
  71. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.ts +100 -0
  72. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/models/download-labels-model.ts +22 -0
  73. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.html +8 -0
  74. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.scss +19 -0
  75. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.ts +26 -0
  76. package/src/lib/http-request-services-demo/request-manager-demo/models/app-session.model.ts +30 -0
  77. package/src/lib/http-request-services-demo/request-manager-demo/models/app.model.ts +19 -0
  78. package/src/lib/http-request-services-demo/request-manager-demo/models/get-sample.model.ts +25 -0
  79. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-ai-prompt.ts +19 -0
  80. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client-details.ts +24 -0
  81. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client-info.ts +30 -0
  82. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client.model.ts +49 -0
  83. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-mapper-client-info.ts +33 -0
  84. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.html +622 -0
  85. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.scss +106 -0
  86. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.ts +687 -0
  87. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.html +418 -0
  88. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.scss +24 -0
  89. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.ts +576 -0
  90. package/src/lib/http-request-services-demo/request-manager-state-demo/services/state-manager-demo.service.ts +89 -0
  91. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/services/state-data-request.service.ts +119 -0
  92. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-ai-messaging/ws-ai-messaging.component.css +0 -0
  93. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-ai-messaging/ws-ai-messaging.component.html +3 -0
  94. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-ai-messaging/ws-ai-messaging.component.ts +16 -0
  95. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-chats/ws-chats.component.css +0 -0
  96. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-chats/ws-chats.component.html +3 -0
  97. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-chats/ws-chats.component.ts +16 -0
  98. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.css +31 -0
  99. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.html +94 -0
  100. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.scss +41 -0
  101. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.spec.ts +203 -0
  102. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.ts +144 -0
  103. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.css +11 -0
  104. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.html +102 -0
  105. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.spec.ts +40 -0
  106. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.ts +230 -0
  107. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.css +30 -0
  108. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.html +172 -0
  109. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.spec.ts +31 -0
  110. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.ts +239 -0
  111. package/src/lib/http-request-services-demo/request-manager-ws-demo/models/oidc-client.model.ts +31 -0
  112. package/src/lib/http-request-services-demo/request-manager-ws-demo/models/user-data.model.ts +32 -0
  113. package/src/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.css +0 -0
  114. package/src/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.html +84 -0
  115. package/src/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.ts +40 -0
  116. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/index.ts +3 -0
  117. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/jwt-token.service.ts +62 -0
  118. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/message-service-demo.service.ts +83 -0
  119. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/notification-service-demo.service.ts +147 -0
  120. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/state-service-demo.service.ts +168 -0
  121. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/download-file/download-file.component.html +53 -0
  122. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/download-file/download-file.component.scss +60 -0
  123. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/download-file/download-file.component.ts +72 -0
  124. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-download.module.ts +28 -0
  125. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-downloader.component.html +10 -0
  126. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-downloader.component.scss +29 -0
  127. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-downloader.component.ts +100 -0
  128. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/models/download-labels-model.ts +22 -0
  129. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/spinner/spinner.component.html +8 -0
  130. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/spinner/spinner.component.scss +19 -0
  131. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/spinner/spinner.component.ts +26 -0
  132. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/app-session.model.ts +30 -0
  133. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/app.model.ts +19 -0
  134. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/get-sample.model.ts +25 -0
  135. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-ai-prompt.ts +19 -0
  136. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-client-details.ts +24 -0
  137. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-client-info.ts +30 -0
  138. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-client.model.ts +49 -0
  139. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-mapper-client-info.ts +33 -0
  140. package/src/lib/http-request-services-demo/request-signals-manager-demo/request-signals-manager-demo.component.html +380 -0
  141. package/src/lib/http-request-services-demo/request-signals-manager-demo/request-signals-manager-demo.component.scss +24 -0
  142. package/src/lib/http-request-services-demo/request-signals-manager-demo/request-signals-manager-demo.component.ts +410 -0
  143. package/src/lib/http-request-services-demo/store-state-manager-demo/models/settings.model.ts +28 -0
  144. package/src/lib/http-request-services-demo/store-state-manager-demo/services/settings-state.service.ts +49 -0
  145. package/src/lib/http-request-services-demo/store-state-manager-demo/store-state-manager-demo.component.css +0 -0
  146. package/src/lib/http-request-services-demo/store-state-manager-demo/store-state-manager-demo.component.html +23 -0
  147. package/src/lib/http-request-services-demo/store-state-manager-demo/store-state-manager-demo.component.ts +36 -0
  148. package/src/lib/http-request-services-demo/store-state-signals-demo/store-state-signals-demo.component.ts +161 -0
  149. package/src/lib/http-request-services-demo/upload-demo/models/index.ts +1 -0
  150. package/src/lib/http-request-services-demo/upload-demo/models/upload-state.model.ts +30 -0
  151. package/src/lib/http-request-services-demo/upload-demo/upload-demo.component.html +89 -0
  152. package/src/lib/http-request-services-demo/upload-demo/upload-demo.component.scss +160 -0
  153. package/src/lib/http-request-services-demo/upload-demo/upload-demo.component.spec.ts +101 -0
  154. package/src/lib/http-request-services-demo/upload-demo/upload-demo.component.ts +136 -0
  155. package/src/lib/index.ts +3 -0
  156. package/src/lib/interceptors/credentials.interceptor.ts +16 -0
  157. package/src/lib/interceptors/index.ts +6 -0
  158. package/src/lib/interceptors/models/error-settings.model.ts +22 -0
  159. package/src/lib/interceptors/models/index.ts +2 -0
  160. package/src/lib/interceptors/proxy-debugger.interceptor.ts +46 -0
  161. package/src/lib/interceptors/request-error.interceptor.ts +65 -0
  162. package/src/lib/interceptors/request-header.interceptor.ts +56 -0
  163. package/src/lib/message-display/README.md +509 -0
  164. package/src/lib/message-display/index.ts +4 -0
  165. package/src/lib/message-display/models/action.model.ts +27 -0
  166. package/src/lib/message-display/models/communication-message.model.ts +77 -0
  167. package/src/lib/message-display/models/display-config.model.ts +35 -0
  168. package/src/lib/message-display/models/display-rule.interface.ts +28 -0
  169. package/src/lib/message-display/models/display-strategy.interface.ts +8 -0
  170. package/src/lib/message-display/models/index.ts +6 -0
  171. package/src/lib/message-display/models/slide.model.ts +24 -0
  172. package/src/lib/message-display/rules/default-display-rules.ts +35 -0
  173. package/src/lib/message-display/services/message-display-router.service.ts +63 -0
  174. package/src/lib/message-display/strategies/snackbar.strategy.ts +46 -0
  175. package/src/lib/models/batch-options.model.ts +33 -0
  176. package/src/lib/models/batch-progress.model.ts +19 -0
  177. package/src/lib/models/batch-request-state.model.ts +40 -0
  178. package/src/lib/models/batch-result.model.ts +30 -0
  179. package/src/lib/models/config-http-options.model.ts +45 -0
  180. package/src/lib/models/config-local-storage-options.model.ts +27 -0
  181. package/src/lib/models/config-options.model.ts +27 -0
  182. package/src/lib/models/config-token.model.ts +9 -0
  183. package/src/lib/models/data-type.enum.ts +5 -0
  184. package/src/lib/models/database-storage.model.ts +24 -0
  185. package/src/lib/models/index.ts +16 -0
  186. package/src/lib/models/retry-options.model.ts +22 -0
  187. package/src/lib/models/upload-validation-error.model.ts +46 -0
  188. package/src/lib/services/SQL-DixieJS service/dexie-query-executor.ts +246 -0
  189. package/src/lib/services/SQL-DixieJS service/dexie-sql.service.ts +31 -0
  190. package/src/lib/services/SQL-DixieJS service/index.ts +4 -0
  191. package/src/lib/services/SQL-DixieJS service/models/execution-plan.model.ts +52 -0
  192. package/src/lib/services/SQL-DixieJS service/models/index.ts +3 -0
  193. package/src/lib/services/SQL-DixieJS service/models/sql-errors.model.ts +13 -0
  194. package/src/lib/services/SQL-DixieJS service/models/sql-options.model.ts +3 -0
  195. package/src/lib/services/SQL-DixieJS service/query-planner.ts +284 -0
  196. package/src/lib/services/SQL-DixieJS service/schema-validator.ts +217 -0
  197. package/src/lib/services/SQL-DixieJS service/sql-parser.ts +35 -0
  198. package/src/lib/services/database-manager-service/database.manager.service.ts +384 -0
  199. package/src/lib/services/database-manager-service/db.storage.service.ts +240 -0
  200. package/src/lib/services/database-manager-service/index.ts +4 -0
  201. package/src/lib/services/database-manager-service/models/index.ts +2 -0
  202. package/src/lib/services/database-manager-service/models/table-schema.ts +33 -0
  203. package/src/lib/services/index.ts +20 -0
  204. package/src/lib/services/local-storage-manager-service/index.ts +4 -0
  205. package/src/lib/services/local-storage-manager-service/local-storage-manager.service.spec.ts +71 -0
  206. package/src/lib/services/local-storage-manager-service/local-storage-manager.service.ts +567 -0
  207. package/src/lib/services/local-storage-manager-service/local-storage-signals-manager.service.spec.ts +67 -0
  208. package/src/lib/services/local-storage-manager-service/local-storage-signals-manager.service.ts +437 -0
  209. package/src/lib/services/local-storage-manager-service/models/global-store-options.model.ts +30 -0
  210. package/src/lib/services/local-storage-manager-service/models/index.ts +6 -0
  211. package/src/lib/services/local-storage-manager-service/models/setting-options.model.ts +35 -0
  212. package/src/lib/services/local-storage-manager-service/models/storage-data.model.ts +24 -0
  213. package/src/lib/services/local-storage-manager-service/models/storage-option.model.ts +32 -0
  214. package/src/lib/services/local-storage-manager-service/models/storage-type.enum.ts +5 -0
  215. package/src/lib/services/request-manager-services/README.md +282 -0
  216. package/src/lib/services/request-manager-services/http-manager-signals.service.ts +674 -0
  217. package/src/lib/services/request-manager-services/http-manager.service.spec.ts +353 -0
  218. package/src/lib/services/request-manager-services/http-manager.service.ts +727 -0
  219. package/src/lib/services/request-manager-services/index.ts +8 -0
  220. package/src/lib/services/request-manager-services/request-signals.service.ts +372 -0
  221. package/src/lib/services/request-manager-services/request.service.ts +435 -0
  222. package/src/lib/services/request-manager-services/rxjs-operators/countdown.ts +17 -0
  223. package/src/lib/services/request-manager-services/rxjs-operators/delay-retry.ts +16 -0
  224. package/src/lib/services/request-manager-services/rxjs-operators/index.ts +4 -0
  225. package/src/lib/services/request-manager-services/rxjs-operators/request-polling.ts +35 -0
  226. package/src/lib/services/request-manager-services/rxjs-operators/request-streaming.ts +468 -0
  227. package/src/lib/services/request-manager-state-service/http-manager-state.store.spec.ts +665 -0
  228. package/src/lib/services/request-manager-state-service/http-manager-state.store.ts +2395 -0
  229. package/src/lib/services/request-manager-state-service/index.ts +3 -0
  230. package/src/lib/services/request-manager-state-service/models/api-request.model.ts +86 -0
  231. package/src/lib/services/request-manager-state-service/models/index.ts +14 -0
  232. package/src/lib/services/request-manager-state-service/models/operation-result.model.ts +18 -0
  233. package/src/lib/services/request-manager-state-service/models/parsing-result.model.ts +21 -0
  234. package/src/lib/services/request-manager-state-service/models/request-options.model.ts +37 -0
  235. package/src/lib/services/request-manager-state-service/models/stream-config.model.ts +20 -0
  236. package/src/lib/services/request-manager-state-service/models/stream-event-metadata.model.ts +23 -0
  237. package/src/lib/services/request-manager-state-service/models/stream-event.model.ts +23 -0
  238. package/src/lib/services/request-manager-state-service/models/stream-output.model.ts +23 -0
  239. package/src/lib/services/request-manager-state-service/models/stream-progress.model.ts +24 -0
  240. package/src/lib/services/request-manager-state-service/models/stream-type.enum.ts +13 -0
  241. package/src/lib/services/request-manager-state-service/models/ws-options.model.ts +42 -0
  242. package/src/lib/services/store-state-manager-service/index.ts +4 -0
  243. package/src/lib/services/store-state-manager-service/models/index.ts +3 -0
  244. package/src/lib/services/store-state-manager-service/models/state-operation-result.model.ts +30 -0
  245. package/src/lib/services/store-state-manager-service/models/state-storage-options.model.ts +24 -0
  246. package/src/lib/services/store-state-manager-service/store-state-manager-signals.service.ts +169 -0
  247. package/src/lib/services/store-state-manager-service/store-state-manager.service.ts +153 -0
  248. package/src/lib/services/utils/app.service.spec.ts +25 -0
  249. package/src/lib/services/utils/app.service.ts +21 -0
  250. package/src/lib/services/utils/encryption/README.md +79 -0
  251. package/src/lib/services/utils/encryption/asymmetrical-encryption.service.ts +282 -0
  252. package/src/lib/services/utils/encryption/encryption-test.service.ts +39 -0
  253. package/src/lib/services/utils/encryption/index.ts +5 -0
  254. package/src/lib/services/utils/encryption/random.ts +81 -0
  255. package/src/lib/services/utils/encryption/symmetrical-encryption.service.ts +106 -0
  256. package/src/lib/services/utils/headers.service.spec.ts +80 -0
  257. package/src/lib/services/utils/headers.service.ts +18 -0
  258. package/src/lib/services/utils/index.ts +9 -0
  259. package/src/lib/services/utils/logger.service.ts +90 -0
  260. package/src/lib/services/utils/models/index.ts +4 -0
  261. package/src/lib/services/utils/models/normalized-request-options.model.ts +24 -0
  262. package/src/lib/services/utils/models/path-tracker-state.model.ts +20 -0
  263. package/src/lib/services/utils/models/query-params-tracker-options.model.ts +24 -0
  264. package/src/lib/services/utils/models/query-tracker-state.model.ts +23 -0
  265. package/src/lib/services/utils/object-merger.service.spec.ts +18 -0
  266. package/src/lib/services/utils/object-merger.service.ts +78 -0
  267. package/src/lib/services/utils/path-query.service.spec.ts +117 -0
  268. package/src/lib/services/utils/path-query.service.ts +69 -0
  269. package/src/lib/services/utils/query-params-tracker.service.ts +442 -0
  270. package/src/lib/services/utils/random-color.utils.ts +83 -0
  271. package/src/lib/services/utils/utils.service.spec.ts +165 -0
  272. package/src/lib/services/utils/utils.service.ts +192 -0
  273. package/src/lib/services/ws-manager-service/index.ts +13 -0
  274. package/src/lib/services/ws-manager-service/message-tracker-signals.service.ts +147 -0
  275. package/src/lib/services/ws-manager-service/message-tracker.service.ts +477 -0
  276. package/src/lib/services/ws-manager-service/models/channel-info.model.ts +29 -0
  277. package/src/lib/services/ws-manager-service/models/channel-message-data.model.ts +24 -0
  278. package/src/lib/services/ws-manager-service/models/channel-message.model.ts +36 -0
  279. package/src/lib/services/ws-manager-service/models/channel-type.enum.ts +6 -0
  280. package/src/lib/services/ws-manager-service/models/communication-type.enum.ts +5 -0
  281. package/src/lib/services/ws-manager-service/models/index.ts +10 -0
  282. package/src/lib/services/ws-manager-service/models/notification-message.model.ts +29 -0
  283. package/src/lib/services/ws-manager-service/models/public-message.model.ts +18 -0
  284. package/src/lib/services/ws-manager-service/models/state-message.model.ts +18 -0
  285. package/src/lib/services/ws-manager-service/models/ws-user.model.ts +38 -0
  286. package/src/lib/services/ws-manager-service/services/index.ts +4 -0
  287. package/src/lib/services/ws-manager-service/services/websocket-message.service.ts +129 -0
  288. package/src/lib/services/ws-manager-service/services/websocket.service.ts +434 -0
  289. package/src/lib/services/ws-manager-service/websocket-service/index.ts +1 -0
  290. package/src/lib/services/ws-manager-service/websocket-service/websocket-manager.service.ts +716 -0
  291. package/src/lib/services/ws-manager-service/websocket-services-complete.spec.ts +596 -0
  292. package/src/lib/services/ws-manager-service/websocket-signals-manager.service.ts +141 -0
  293. package/src/public-api.ts +19 -0
  294. package/tsconfig.lib.json +34 -0
  295. package/tsconfig.lib.prod.json +10 -0
  296. package/tsconfig.spec.json +14 -0
  297. package/fesm2022/http-request-manager.mjs +0 -13688
  298. package/fesm2022/http-request-manager.mjs.map +0 -1
  299. package/http-request-manager-18.15.33.tgz +0 -0
  300. package/types/http-request-manager.d.ts +0 -3968
@@ -0,0 +1,1391 @@
1
+ # HTTP Manager State Service
2
+
3
+ The `HTTPManagerStateService` is a comprehensive state management service that combines HTTP requests, WebSocket real-time updates, and IndexedDB persistence.
4
+
5
+ ## Features
6
+
7
+ - **HTTP CRUD Operations**: Fetch, create, update, and delete records
8
+ - **WebSocket Integration**: Real-time synchronization across clients
9
+ - **IndexedDB Persistence**: Cache data locally with expiration
10
+ - **State Management**: Built on NgRx ComponentStore
11
+ - **Automatic Retry**: Configurable retry logic for failed requests
12
+
13
+ ## Usage
14
+
15
+ ### Basic Setup
16
+
17
+ ```typescript
18
+ import { HTTPManagerStateService, ApiRequest, DataType, DatabaseStorage } from 'http-request-manager';
19
+
20
+ @Injectable({
21
+ providedIn: 'root'
22
+ })
23
+ export class MyStateService extends HTTPManagerStateService<MyDataType> {
24
+
25
+ constructor() {
26
+ super(
27
+ ApiRequest.adapt({
28
+ server: 'https://api.example.com',
29
+ path: ['items'],
30
+ adapter: MyDataType.adapt // Model adapter
31
+ }),
32
+ DataType.ARRAY,
33
+ DatabaseStorage.adapt({
34
+ table: 'my_items',
35
+ expiresIn: '1h' // Cache expiration
36
+ })
37
+ );
38
+ }
39
+ }
40
+ ```
41
+
42
+ ### Database Operations
43
+
44
+ #### Clear Database Table
45
+
46
+ Clears all records from the configured IndexedDB table and resets in-memory state.
47
+
48
+ ```typescript
49
+ // Clear the database (subscription handled internally)
50
+ myStateService.clearDatabase();
51
+
52
+ // This will:
53
+ // 1. Clear all records from the IndexedDB table
54
+ // 2. Clear the in-memory state (set to empty array or object)
55
+ // 3. Log success/error messages to console
56
+ // 4. NOT re-fetch from API - data remains empty until manually refreshed
57
+ // 5. NOT clear localStorage metadata (expiration info is preserved)
58
+ ```
59
+
60
+ **Example in Component:**
61
+
62
+ ```typescript
63
+ @Component({
64
+ selector: 'app-my-component',
65
+ template: `
66
+ <button (click)="onClearDatabase()">Clear Cache</button>
67
+ `
68
+ })
69
+ export class MyComponent {
70
+ myStateService = inject(MyStateService);
71
+
72
+ onClearDatabase() {
73
+ // Simple call - no subscription needed
74
+ this.myStateService.clearDatabase();
75
+ }
76
+ }
77
+ ```
78
+
79
+ **Console Output:**
80
+ ```
81
+ 🗑️ Clearing database table: my_items
82
+ clearTable: Starting clear for table: my_items
83
+ clearTable: Clearing table 'my_items'...
84
+ clearTable: ✅ Table 'my_items' cleared successfully
85
+ ✅ Database table my_items cleared successfully
86
+ ```
87
+
88
+ ### CRUD Operations
89
+
90
+ ```typescript
91
+ // Fetch all records
92
+ service.fetchRecords();
93
+
94
+ // Fetch single record
95
+ service.fetchRecord({ path: ['items', 123] }, 'GET');
96
+
97
+ // Create record
98
+ service.createRecord(newData, { path: ['items'] });
99
+
100
+ // Update record
101
+ service.updateRecord(updatedData, { path: ['items', 123] });
102
+
103
+ // Delete record
104
+ service.deleteRecord({ path: ['items', 123] });
105
+ ```
106
+
107
+ ### Request Tracking Options (Database Only)
108
+
109
+ The state manager supports query-tracking options on `fetchRecords` and `fetchStream`.
110
+
111
+ ```typescript
112
+ service.fetchRecords(RequestOptions.adapt({
113
+ path: ['ai/pagination?page=0&size=25'],
114
+ ignoreQueryParams: ['page', 'size'],
115
+ queryParamsExpiresIn: '10s',
116
+ watchParams: ['category', 'status'],
117
+ watchExpiresAt: 1715904000
118
+ }));
119
+ ```
120
+
121
+ Options:
122
+
123
+ - `ignoreQueryParams`: Query parameter keys to exclude from request-change tracking.
124
+ - `queryParamsExpiresIn`: Expiry duration for tracked values (e.g., `'10s'`, `'5mn'`, `'1h'`).
125
+ - `watchParams`: Specific query parameter keys to watch for change detection in variation mode. When set, only these params are tracked; others are ignored.
126
+ - `watchExpiresAt`: Epoch timestamp (in seconds) when tracked values expire. Alternative to `queryParamsExpiresIn` for absolute expiry.
127
+
128
+ Scope and behavior:
129
+
130
+ - Database enabled (`DatabaseStorage` configured): tracker is active and can prevent repeated identical API calls until expiry resets tracked values.
131
+ - Database disabled: tracker is not enabled; requests go straight to API.
132
+ - `forceRefresh: true` bypasses tracking and always makes the API request.
133
+
134
+ ### WebSocket Integration
135
+
136
+ ```typescript
137
+ // Automatic real-time sync when WebSocket is configured
138
+ ApiRequest.adapt({
139
+ server: 'https://api.example.com',
140
+ ws: {
141
+ wsServer: 'wss://ws.example.com',
142
+ id: 'my-channel',
143
+ jwtToken: 'your-jwt-token',
144
+ retry: { times: 3, delay: 5 }
145
+ }
146
+ });
147
+ ```
148
+
149
+ ## Configuration Options
150
+
151
+ ### ApiRequest
152
+ - `server`: Backend API server URL
153
+ - `path`: Array of path segments
154
+ - `adapter`: Function to transform API response to your model
155
+ - `ws`: WebSocket configuration
156
+ - `retry`: Retry options for failed requests
157
+
158
+ ### DatabaseStorage
159
+ - `table`: IndexedDB table name
160
+ - `expiresIn`: Cache expiration (e.g., '1h', '30mn', '5mn')
161
+
162
+ ### DataType
163
+ - `ARRAY`: For list data (default)
164
+ - `OBJECT`: For single object data
165
+
166
+ ## Notes
167
+
168
+ - The `clearDatabase()` method handles subscription internally for simplicity
169
+ - Database operations are asynchronous and logged to console
170
+ - Clearing the database does NOT trigger a refresh - call `fetchRecords()` after clearing if needed
171
+
172
+ The `HTTPManagerStateService` is a comprehensive state management service that combines HTTP requests, WebSocket real-time updates, and IndexedDB persistence.
173
+
174
+ ## Features
175
+
176
+ - **HTTP CRUD Operations**: Fetch, create, update, and delete records
177
+ - **WebSocket Integration**: Real-time synchronization across clients
178
+ - **IndexedDB Persistence**: Cache data locally with expiration
179
+ - **State Management**: Built on NgRx ComponentStore
180
+ - **Automatic Retry**: Configurable retry logic for failed requests
181
+
182
+ ## Usage
183
+
184
+ ### Basic Setup
185
+
186
+ ```typescript
187
+ import { HTTPManagerStateService, ApiRequest, DataType, DatabaseStorage } from 'http-request-manager';
188
+
189
+ @Injectable({
190
+ providedIn: 'root'
191
+ })
192
+ export class MyStateService extends HTTPManagerStateService<MyDataType> {
193
+
194
+ constructor() {
195
+ super(
196
+ ApiRequest.adapt({
197
+ server: 'https://api.example.com',
198
+ path: ['items'],
199
+ adapter: MyDataType.adapt // Model adapter
200
+ }),
201
+ DataType.ARRAY,
202
+ DatabaseStorage.adapt({
203
+ table: 'my_items',
204
+ expiresIn: '1h' // Cache expiration
205
+ })
206
+ );
207
+ }
208
+ }
209
+ ```
210
+
211
+ ### Database Operations
212
+
213
+ #### Clear Database Table
214
+
215
+ Clears all records from the configured IndexedDB table and resets in-memory state.
216
+
217
+ ```typescript
218
+ // Clear the database (subscription handled internally)
219
+ myStateService.clearDatabase();
220
+
221
+ // This will:
222
+ // 1. Clear all records from the IndexedDB table
223
+ // 2. Clear the in-memory state (set to empty array or object)
224
+ // 3. Log success/error messages to console
225
+ // 4. NOT re-fetch from API - data remains empty until manually refreshed
226
+ // 5. NOT clear localStorage metadata (expiration info is preserved)
227
+ ```
228
+
229
+ **Example in Component:**
230
+
231
+ ```typescript
232
+ @Component({
233
+ selector: 'app-my-component',
234
+ template: `
235
+ <button (click)="onClearDatabase()">Clear Cache</button>
236
+ `
237
+ })
238
+ export class MyComponent {
239
+ myStateService = inject(MyStateService);
240
+
241
+ onClearDatabase() {
242
+ // Simple call - no subscription needed
243
+ this.myStateService.clearDatabase();
244
+ }
245
+ }
246
+ ```
247
+
248
+ **Console Output:**
249
+ ```
250
+ 🗑️ Clearing database table: my_items
251
+ clearTable: Starting clear for table: my_items
252
+ clearTable: Clearing table 'my_items'...
253
+ clearTable: ✅ Table 'my_items' cleared successfully
254
+ ✅ Database table my_items cleared successfully
255
+ ```
256
+
257
+ ### CRUD Operations
258
+
259
+ ```typescript
260
+ // Fetch all records
261
+ service.fetchRecords();
262
+
263
+ // Fetch single record
264
+ service.fetchRecord({ path: ['items', 123] }, 'GET');
265
+
266
+ // Create record
267
+ service.createRecord(newData, { path: ['items'] });
268
+
269
+ // Update record
270
+ service.updateRecord(updatedData, { path: ['items', 123] });
271
+
272
+ // Delete record
273
+ service.deleteRecord({ path: ['items', 123] });
274
+ ```
275
+
276
+ ### WebSocket Integration
277
+
278
+ ```typescript
279
+ // Automatic real-time sync when WebSocket is configured
280
+ ApiRequest.adapt({
281
+ server: 'https://api.example.com',
282
+ ws: {
283
+ wsServer: 'wss://ws.example.com',
284
+ id: 'my-channel',
285
+ jwtToken: 'your-jwt-token',
286
+ retry: { times: 3, delay: 5 }
287
+ }
288
+ });
289
+ ```
290
+
291
+ ## Configuration Options
292
+
293
+ ### ApiRequest
294
+ - `server`: Backend API server URL
295
+ - `path`: Array of path segments
296
+ - `adapter`: Function to transform API response to your model
297
+ - `ws`: WebSocket configuration
298
+ - `retry`: Retry options for failed requests
299
+
300
+ ### DatabaseStorage
301
+ - `table`: IndexedDB table name
302
+ - `expiresIn`: Cache expiration (e.g., '1h', '30mn', '5mn')
303
+
304
+ ### DataType
305
+ - `ARRAY`: For list data (default)
306
+ - `OBJECT`: For single object data
307
+
308
+ ## Notes
309
+
310
+ - The `clearDatabase()` method handles subscription internally for simplicity
311
+ - Database operations are asynchronous and logged to console
312
+ - Clearing the database does NOT trigger a refresh - call `fetchRecords()` after clearing if needed
313
+
314
+ The `HTTPManagerStateService` is a comprehensive state management solution that extends NGRX `ComponentStore` to provide unified HTTP request handling, WebSocket real-time synchronization, and offline-first data persistence.
315
+
316
+ ## Overview
317
+
318
+ This service serves as the central hub for managing application state, combining:
319
+ - **HTTP CRUD operations** with automatic local state updates
320
+ - **WebSocket integration** for real-time multi-user synchronization
321
+ - **IndexedDB persistence** for offline-first applications
322
+ - **Pagination and streaming** support out of the box
323
+ - **Message tracking** with guaranteed delivery
324
+
325
+ ### Architecture
326
+
327
+ ```
328
+ ┌─────────────────────────────────────────────────────────────┐
329
+ │ HTTPManagerStateService │
330
+ │ (ComponentStore) │
331
+ ├─────────────────────────────────────────────────────────────┤
332
+ │ │
333
+ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
334
+ │ │ HTTP │ │ WebSocket │ │ Database │ │
335
+ │ │ Manager │◀─ Manager │◀─┤ Manager │ │
336
+ │ │ Service │ │ (Singleton) │ │ Service │ │
337
+ │ └──────────────┘ └──────────────┘ └──────────────┘ │
338
+ │ │ │ │ │
339
+ │ ▼ ▼ ▼ │
340
+ │ ┌─────────────────────────────────────────────────────┐ │
341
+ │ │ Local State (ComponentStore) │ │
342
+ │ │ - data$ (records) │ │
343
+ │ │ - page$, totalPages$, percentage$ │ │
344
+ │ │ - isPending$, error$ │ │
345
+ │ │ - userList$, channels$, messages$ │ │
346
+ │ └─────────────────────────────────────────────────────┘ │
347
+ └─────────────────────────────────────────────────────────────┘
348
+ ```
349
+
350
+ ### Key Features
351
+
352
+ - **ComponentStore Integration** - Extends NGRX ComponentStore for localized, performant state management
353
+ - **Automatic CRUD Updates** - `createRecord`, `updateRecord`, and `deleteRecord` automatically update local state and sync via WebSocket
354
+ - **WebSocket Real-Time Sync** - Multi-user synchronization with channel-based messaging and user presence tracking
355
+ - **Guaranteed Message Delivery** - MessageTrackerService ensures no messages are missed during disconnections
356
+ - **Database Support** - IndexedDB caching integration for offline-first applications with automatic sync
357
+ - **Pagination State** - Built-in tracking for page, totalPages, and loading percentage
358
+ - **Streaming Support** - Real-time data streaming with AI streaming patterns
359
+ - **Notification System** - Dedicated notification channels with date filtering and latest notification tracking
360
+ - **User Presence** - Track active users per channel and across all channels
361
+
362
+ ## Installation
363
+
364
+ ```typescript
365
+ import { HttpRequestManagerModule } from 'http-request-manager';
366
+
367
+ @NgModule({
368
+ imports: [HttpRequestManagerModule.forRoot({})]
369
+ })
370
+ export class AppModule { }
371
+ ```
372
+
373
+ ## Basic Usage
374
+
375
+ ### Creating a State Service
376
+
377
+ ```typescript
378
+ import { Injectable } from '@angular/core';
379
+ import { HTTPManagerStateService, ApiRequest, DataType } from 'http-request-manager';
380
+
381
+ interface User {
382
+ id: number;
383
+ name: string;
384
+ email: string;
385
+ active: boolean;
386
+ }
387
+
388
+ @Injectable({
389
+ providedIn: 'root'
390
+ })
391
+ export class UserStateService extends HTTPManagerStateService<User> {
392
+
393
+ constructor() {
394
+ super(
395
+ ApiRequest.adapt({
396
+ server: 'http://localhost:8080',
397
+ path: ['users'],
398
+ adapter: User.adapt, // Required for Database Storage
399
+ ws: {
400
+ id: 'USERS123', // Base name - automatically becomes SYS-USERS123
401
+ wsServer: 'ws://localhost:8080',
402
+ retry: { times: 3, delay: 5 }
403
+ }
404
+ }),
405
+ DataType.ARRAY,
406
+ DatabaseStorage.adapt({
407
+ table: 'users-cache',
408
+ expiresIn: '1d' // Cache for 1 day
409
+ })
410
+ );
411
+ }
412
+
413
+ // Public API methods
414
+ loadUsers() {
415
+ this.fetchRecords();
416
+ }
417
+
418
+ addUser(user: Omit<User, 'id'>) {
419
+ this.createRecord(user);
420
+ }
421
+
422
+ updateUser(user: User) {
423
+ this.updateRecord(user);
424
+ }
425
+
426
+ deleteUser(id: number) {
427
+ this.deleteRecord(id);
428
+ }
429
+
430
+ getUser(id: number) {
431
+ return this.selectRecord$(id);
432
+ }
433
+ }
434
+ ```
435
+
436
+ ### Using in Components
437
+
438
+ ```typescript
439
+ import { Component, inject } from '@angular/core';
440
+ import { UserStateService } from './user-state.service';
441
+
442
+ @Component({
443
+ selector: 'app-users',
444
+ template: `
445
+ <div class="user-management">
446
+ <h2>User Management</h2>
447
+
448
+ <!-- Loading State -->
449
+ <div *ngIf="store.isPending$ | async">
450
+ <div class="loading-spinner">Loading users...</div>
451
+ </div>
452
+
453
+ <!-- Error State -->
454
+ <div *ngIf="store.error$ | async as error" class="error">
455
+ Error: {{ error.message }}
456
+ </div>
457
+
458
+ <!-- User List -->
459
+ <div class="user-grid">
460
+ <div *ngFor="let user of store.data$ | async" class="user-card">
461
+ <div class="user-info">
462
+ <h3>{{ user.name }}</h3>
463
+ <p>{{ user.email }}</p>
464
+ <span class="user-status"
465
+ [class.active]="user.active"
466
+ [class.inactive]="!user.active">
467
+ {{ user.active ? 'Active' : 'Inactive' }}
468
+ </span>
469
+ </div>
470
+
471
+ <div class="user-actions">
472
+ <button (click)="store.updateUser({...user, active: !user.active})">
473
+ {{ user.active ? 'Deactivate' : 'Activate' }}
474
+ </button>
475
+ <button (click)="store.deleteUser(user.id)" class="delete">
476
+ Delete
477
+ </button>
478
+ </div>
479
+ </div>
480
+ </div>
481
+
482
+ <!-- Add User Form -->
483
+ <div class="add-user-form">
484
+ <h3>Add New User</h3>
485
+ <form (ngSubmit)="addUser()">
486
+ <input [(ngModel)]="newUser.name" name="name" placeholder="Name" required>
487
+ <input [(ngModel)]="newUser.email" name="email" placeholder="Email" required>
488
+ <label>
489
+ <input type="checkbox" [(ngModel)]="newUser.active" name="active">
490
+ Active
491
+ </label>
492
+ <button type="submit">Add User</button>
493
+ </form>
494
+ </div>
495
+ </div>
496
+ `
497
+ })
498
+ export class UsersComponent {
499
+ store = inject(UserStateService);
500
+
501
+ newUser = {
502
+ name: '',
503
+ email: '',
504
+ active: true
505
+ };
506
+
507
+ ngOnInit() {
508
+ this.store.loadUsers();
509
+ }
510
+
511
+ addUser() {
512
+ if (this.newUser.name && this.newUser.email) {
513
+ this.store.addUser(this.newUser);
514
+ this.newUser = { name: '', email: '', active: true };
515
+ }
516
+ }
517
+ }
518
+ ```
519
+
520
+ ## API Reference
521
+
522
+ ### State Interface
523
+
524
+ The service manages state with the following interface:
525
+
526
+ ```typescript
527
+ interface State<T> {
528
+ records: T[]; // Array of entities
529
+ record: T | null; // Single selected entity
530
+ page: number; // Current page
531
+ totalPages: number; // Total pages
532
+ isPending: boolean; // Loading state
533
+ error: any; // Error state
534
+ }
535
+ ```
536
+
537
+ ### WSOptions Model (Updated)
538
+
539
+ The `WSOptions` model has been updated with the following changes:
540
+
541
+ ```typescript
542
+ interface WSOptionsInterface {
543
+ id: string,
544
+ wsServer: string,
545
+ jwtToken: string,
546
+ permissions?: string[],
547
+ channels?: string[], // ✅ Available
548
+ user?: any,
549
+ retry?: RetryOptions,
550
+ // wsUpdateChannels?: string[] ❌ Removed
551
+ }
552
+ ```
553
+
554
+ **Breaking Changes:**
555
+ - `wsUpdateChannels` property has been **removed** from `WSOptionsInterface` and `WSOptions` class
556
+ - Channel management is now handled through the `channels` array and automatic detection
557
+ - Legacy message format support is maintained for backward compatibility
558
+
559
+ ### Selectors
560
+
561
+ #### data$: Observable<T[]>
562
+
563
+ Get all records from the state:
564
+
565
+ ```typescript
566
+ users$ = this.store.data$;
567
+ ```
568
+
569
+ #### record$: Observable<T | null>
570
+
571
+ Get the currently selected record:
572
+
573
+ ```typescript
574
+ selectedUser$ = this.store.record$;
575
+ ```
576
+
577
+ #### selectRecord$(id: any): Observable<T | undefined>
578
+
579
+ Get a specific record by ID:
580
+
581
+ ```typescript
582
+ user$ = this.store.selectRecord$(123);
583
+ ```
584
+
585
+ #### isPending$: Observable<boolean>
586
+
587
+ Check if any operation is in progress:
588
+
589
+ ```typescript
590
+ loading$ = this.store.isPending$;
591
+ ```
592
+
593
+ #### error$: Observable<any>
594
+
595
+ Get the current error state:
596
+
597
+ ```typescript
598
+ error$ = this.store.error$;
599
+ ```
600
+
601
+ #### operationSuccess$: Observable\<OperationResultModel | null\>
602
+
603
+ Get feedback after `createRecord`, `updateRecord`, or `deleteRecord` operations. Emits `{ success: true, operation: 'CREATE' | 'UPDATE' | 'DELETE' }` when data is successfully pushed into state.
604
+
605
+ ```typescript
606
+ this.store.operationSuccess$.subscribe(result => {
607
+ if (result?.success) {
608
+ // result.operation tells you which CRUD action completed
609
+ showSuccessToast(`${result.operation} succeeded!`);
610
+ }
611
+ });
612
+ ```
613
+
614
+ **Example in Component:**
615
+
616
+ ```typescript
617
+ @Component({
618
+ selector: 'app-users',
619
+ template: `
620
+ <button (click)="store.deleteUser(user.id)">Delete</button>
621
+ <div *ngIf="lastOperation" class="toast">
622
+ {{ lastOperation.operation }} {{ lastOperation.success ? 'succeeded' : 'failed' }}
623
+ </div>
624
+ `
625
+ })
626
+ export class UsersComponent {
627
+ store = inject(UserStateService);
628
+ lastOperation: OperationResultModel | null = null;
629
+
630
+ constructor() {
631
+ this.store.operationSuccess$.subscribe(result => {
632
+ this.lastOperation = result;
633
+ // Auto-clear after 3 seconds
634
+ setTimeout(() => this.lastOperation = null, 3000);
635
+ });
636
+ }
637
+ }
638
+ ```
639
+
640
+ > **Note:** `operationSuccess$` only emits on successful HTTP responses that update local state. It does not emit on errors — use `error$` for error handling.
641
+
642
+ #### page$: Observable<number>
643
+
644
+ Get the current page number:
645
+
646
+ ```typescript
647
+ currentPage$ = this.store.page$;
648
+ ```
649
+
650
+ #### totalPages$: Observable<number>
651
+
652
+ Get the total number of pages:
653
+
654
+ ```typescript
655
+ totalPages$ = this.store.totalPages$;
656
+ ```
657
+
658
+ ### CRUD Methods
659
+
660
+ #### fetchRecords(params?: any)
661
+
662
+ Fetch records from the API:
663
+
664
+ ```typescript
665
+ // Basic fetch
666
+ this.store.fetchRecords();
667
+
668
+ // Fetch with parameters
669
+ this.store.fetchRecords({ page: 1, limit: 10, search: 'john' });
670
+ ```
671
+
672
+ #### createRecord(record: T)
673
+
674
+ Create a new record and update state:
675
+
676
+ ```typescript
677
+ this.store.createRecord({
678
+ name: 'John Doe',
679
+ email: 'john@example.com',
680
+ active: true
681
+ });
682
+ ```
683
+
684
+ #### updateRecord(record: T)
685
+
686
+ Update an existing record and update state:
687
+
688
+ ```typescript
689
+ this.store.updateRecord({
690
+ id: 123,
691
+ name: 'John Smith',
692
+ email: 'john.smith@example.com',
693
+ active: true
694
+ });
695
+ ```
696
+
697
+ #### deleteRecord(id: any)
698
+
699
+ Delete a record and update state:
700
+
701
+ ```typescript
702
+ this.store.deleteRecord(123);
703
+ ```
704
+
705
+ #### setPage(page: number)
706
+
707
+ Set the current page:
708
+
709
+ ```typescript
710
+ this.store.setPage(2);
711
+ ```
712
+
713
+ #### setTotalPages(total: number)
714
+
715
+ Set the total number of pages:
716
+
717
+ ```typescript
718
+ this.store.setTotalPages(10);
719
+ ```
720
+
721
+ ## WebSocket Integration
722
+
723
+ The HTTPManagerStateService automatically handles WebSocket connections for real-time state synchronization.
724
+
725
+ ### Channel Types
726
+
727
+ The service uses three types of WebSocket channels:
728
+
729
+ | Channel Type | Prefix | Description | Purpose |
730
+ |--------------|--------|-------------|---------|
731
+ | **STATE** | `SYS-` | State synchronization | CRUD operations sync |
732
+ | **MESSAGE** | `MES-` | Messaging channels | Real-time messaging |
733
+ | **NOTIFICATION** | `PUB-` | Notification channels | System notifications |
734
+
735
+ ### Channel Management (Updated)
736
+
737
+ > **Breaking Change:** The `wsUpdateChannels` property has been removed from `WSOptionsInterface` and `WSOptions` class.
738
+
739
+ Channel management has been improved and simplified:
740
+
741
+ 1. **Automatic Channel Detection**: The service now automatically constructs the expected channel name from the API path and environment configuration
742
+ 2. **Dynamic Channel Matching**: Messages are matched against expected channels based on the pattern: `${env}/${path.join('/')}`
743
+ 3. **Fallback Support**: Legacy message formats are still supported for backward compatibility
744
+
745
+ ```typescript
746
+ // Before (deprecated)
747
+ ws: {
748
+ id: 'USERS123',
749
+ wsUpdateChannels: ['MES-users', 'MES-updates'], // ❌ No longer supported
750
+ wsServer: 'ws://localhost:8080'
751
+ }
752
+
753
+ // After (current)
754
+ ws: {
755
+ id: 'USERS123',
756
+ channels: ['custom-channel-1', 'custom-channel-2'], // ✅ Use channels array
757
+ wsServer: 'ws://localhost:8080'
758
+ }
759
+ ```
760
+
761
+ ### Configuration
762
+
763
+ ```typescript
764
+ constructor() {
765
+ super(
766
+ ApiRequest.adapt({
767
+ server: 'http://localhost:8080',
768
+ path: ['users'],
769
+ ws: {
770
+ id: 'USERS123', // Base name becomes SYS-USERS123
771
+ wsServer: 'ws://localhost:8080',
772
+ jwtToken: 'your-jwt-token',
773
+ retry: { times: 3, delay: 5 }
774
+ }
775
+ }),
776
+ DataType.ARRAY
777
+ );
778
+ }
779
+ ```
780
+
781
+ > **Note:** The `wsUpdateChannels` property has been removed from `WSOptions`. WebSocket channel management is now handled dynamically through the `channels` property and automatic channel detection based on the API path and environment configuration.
782
+
783
+ ### WebSocket Observables
784
+
785
+ #### connectionStatus$: Observable<boolean>
786
+
787
+ Monitor WebSocket connection status:
788
+
789
+ ```typescript
790
+ connectionStatus$ = this.store.connectionStatus$;
791
+
792
+ // Usage
793
+ <div *ngIf="store.connectionStatus$ | async; disconnected" class="connection-status">
794
+ Connected
795
+ </div>
796
+
797
+ <ng-template #disconnected>
798
+ <div class="connection-status offline">
799
+ Reconnecting...
800
+ </div>
801
+ </ng-template>
802
+ ```
803
+
804
+ #### communicationMessages$: Observable<any[]>
805
+
806
+ Monitor incoming messages:
807
+
808
+ ```typescript
809
+ messages$ = this.store.communicationMessages$;
810
+ ```
811
+
812
+ #### notificationMessages$: Observable<any[]>
813
+
814
+ Monitor notifications:
815
+
816
+ ```typescript
817
+ notifications$ = this.store.notificationMessages$;
818
+ ```
819
+
820
+ ### WebSocket Methods
821
+
822
+ #### initializeConnection(wsServer: string, jwtToken: string, user: any)
823
+
824
+ Initialize WebSocket connection:
825
+
826
+ ```typescript
827
+ this.store.initializeConnection(
828
+ 'ws://localhost:8080',
829
+ 'jwt-token-here',
830
+ { id: 1, name: 'John Doe', email: 'john@example.com' }
831
+ );
832
+ ```
833
+
834
+ #### setApiRequestOptions(options: ApiRequest)
835
+
836
+ Update API and WebSocket configuration at runtime:
837
+
838
+ ```typescript
839
+ this.store.setApiRequestOptions(
840
+ ApiRequest.adapt({
841
+ ...this.store.apiRequestOptions,
842
+ ws: {
843
+ ...this.store.apiRequestOptions.ws,
844
+ wsServer: 'wss://new-server.com/ws'
845
+ }
846
+ })
847
+ );
848
+ ```
849
+
850
+ #### createChannel(channelName: string)
851
+
852
+ Create a new messaging channel:
853
+
854
+ ```typescript
855
+ // Creates PUB-{channelName}
856
+ this.store.createChannel('general-chat');
857
+ ```
858
+
859
+ #### subscribeToChannel(channelName: string)
860
+
861
+ Subscribe to a messaging channel:
862
+
863
+ ```typescript
864
+ // Subscribes to PUB-{channelName}
865
+ this.store.subscribeToChannel('general-chat');
866
+ ```
867
+
868
+ #### unsubscribeFromChannel(channelName: string)
869
+
870
+ Unsubscribe from a channel:
871
+
872
+ ```typescript
873
+ this.store.unsubscribeFromChannel('general-chat');
874
+ ```
875
+
876
+ #### sendMessage(content: any, channels: string[])
877
+
878
+ Send a message to specific channels:
879
+
880
+ ```typescript
881
+ this.store.sendMessage(
882
+ { message: 'Hello everyone!' },
883
+ ['general-chat', 'team-updates']
884
+ );
885
+ ```
886
+
887
+ **Implementation Note:** The service now uses optimized batch messaging with `sendChannelMessageToChannels()` for better performance when sending to multiple channels simultaneously.
888
+
889
+ ### Real-time CRUD Operations
890
+
891
+ The service automatically syncs state changes via WebSocket:
892
+
893
+ ```typescript
894
+ // When createRecord() is called:
895
+ // 1. Makes HTTP POST request
896
+ // 2. On success, updates local state
897
+ // 3. Sends WebSocket message to SYS-{id} channel
898
+ // 4. Other clients receive the message and update their state
899
+
900
+ // When other clients call createRecord:
901
+ // 1. They send WebSocket message to SYS-{id} channel
902
+ // 2. This client receives the message
903
+ // 3. Automatically calls fetchRecords() to get updated data
904
+ ```
905
+
906
+ **Updated Message Handling:**
907
+ The service now implements enhanced message processing:
908
+ - **Automatic Channel Detection**: Messages are matched against expected channels using `${env}/${path.join('/')}` pattern
909
+ - **Optimized Batch Messaging**: Uses `sendChannelMessageToChannels()` for better performance
910
+ - **Legacy Format Support**: Maintains backward compatibility with older message formats
911
+ - **Enhanced Error Handling**: Improved error handling during service initialization
912
+
913
+ ## Database Storage Integration
914
+
915
+ For offline-first applications, configure IndexedDB caching:
916
+
917
+ ```typescript
918
+ @Injectable()
919
+ export class UserStateService extends HTTPManagerStateService<User> {
920
+
921
+ constructor() {
922
+ super(
923
+ ApiRequest.adapt({
924
+ server: 'http://localhost:8080',
925
+ path: ['users'],
926
+ adapter: User.adapt // Required for Database Storage
927
+ }),
928
+ DataType.ARRAY,
929
+ DatabaseStorage.adapt({
930
+ table: 'users-cache',
931
+ expiresIn: '1d' // Cache expires in 1 day
932
+ })
933
+ );
934
+ }
935
+ }
936
+ ```
937
+
938
+ ### Caching Behavior
939
+
940
+ 1. **First Request**: Fetches from server and saves to IndexedDB
941
+ 2. **Subsequent Requests**: Checks IndexedDB first, uses cached data if valid
942
+ 3. **Cache Expiry**: Automatically fetches from server when cache expires
943
+ 4. **Offline Mode**: Uses cached data when network is unavailable
944
+
945
+ ## Advanced Examples
946
+
947
+ ### Pagination State Service
948
+
949
+ ```typescript
950
+ @Injectable()
951
+ export class PaginatedUserStateService extends HTTPManagerStateService<User> {
952
+
953
+ private currentPage = signal(1);
954
+ private pageSize = signal(10);
955
+ private searchQuery = signal('');
956
+ private sortBy = signal('name');
957
+ private sortOrder = signal<'asc' | 'desc'>('asc');
958
+
959
+ // Computed selectors
960
+ totalPages = computed(() => Math.ceil(this.store.data$().length / this.pageSize()));
961
+
962
+ paginatedData = computed(() => {
963
+ const data = this.store.data$();
964
+ const start = (this.currentPage() - 1) * this.pageSize();
965
+ const end = start + this.pageSize();
966
+ return data.slice(start, end);
967
+ });
968
+
969
+ constructor() {
970
+ super(
971
+ ApiRequest.adapt({
972
+ server: 'http://localhost:8080',
973
+ path: ['users'],
974
+ adapter: User.adapt
975
+ }),
976
+ DataType.ARRAY
977
+ );
978
+ }
979
+
980
+ loadUsers() {
981
+ const params = {
982
+ page: this.currentPage(),
983
+ limit: this.pageSize(),
984
+ search: this.searchQuery(),
985
+ sortBy: this.sortBy(),
986
+ sortOrder: this.sortOrder()
987
+ };
988
+
989
+ this.fetchRecords(params);
990
+ }
991
+
992
+ setPage(page: number) {
993
+ this.currentPage.set(page);
994
+ this.loadUsers();
995
+ }
996
+
997
+ setPageSize(size: number) {
998
+ this.pageSize.set(size);
999
+ this.currentPage.set(1); // Reset to first page
1000
+ this.loadUsers();
1001
+ }
1002
+
1003
+ setSearchQuery(query: string) {
1004
+ this.searchQuery.set(query);
1005
+ this.currentPage.set(1); // Reset to first page
1006
+ this.loadUsers();
1007
+ }
1008
+
1009
+ setSorting(sortBy: string, order: 'asc' | 'desc') {
1010
+ this.sortBy.set(sortBy);
1011
+ this.sortOrder.set(order);
1012
+ this.currentPage.set(1); // Reset to first page
1013
+ this.loadUsers();
1014
+ }
1015
+ }
1016
+ ```
1017
+
1018
+ ### Real-time Chat with State Management
1019
+
1020
+ ```typescript
1021
+ @Injectable()
1022
+ export class ChatStateService extends HTTPManagerStateService<ChatMessage> {
1023
+
1024
+ private currentUser = signal<any>(null);
1025
+ private activeChannel = signal<string>('general');
1026
+
1027
+ // Observables
1028
+ messages$ = this.store.data$;
1029
+ channelUsers$ = this.store.communicationMessages$;
1030
+ connectionStatus$ = this.store.connectionStatus$;
1031
+
1032
+ constructor() {
1033
+ super(
1034
+ ApiRequest.adapt({
1035
+ server: 'http://localhost:8080',
1036
+ path: ['messages'],
1037
+ adapter: ChatMessage.adapt,
1038
+ ws: {
1039
+ id: 'CHAT_WS',
1040
+ wsServer: 'ws://localhost:8080'
1041
+ }
1042
+ }),
1043
+ DataType.ARRAY
1044
+ );
1045
+ }
1046
+
1047
+ initializeChat(user: any) {
1048
+ this.currentUser.set(user);
1049
+ this.store.initializeConnection(
1050
+ 'ws://localhost:8080',
1051
+ user.jwtToken,
1052
+ user
1053
+ );
1054
+ }
1055
+
1056
+ joinChannel(channelName: string) {
1057
+ this.activeChannel.set(channelName);
1058
+ this.store.createChannel(channelName);
1059
+ this.store.subscribeToChannel(channelName);
1060
+ }
1061
+
1062
+ leaveChannel(channelName: string) {
1063
+ this.store.unsubscribeFromChannel(channelName);
1064
+ if (this.activeChannel() === channelName) {
1065
+ this.activeChannel.set('general');
1066
+ }
1067
+ }
1068
+
1069
+ sendMessage(message: string) {
1070
+ const channel = this.activeChannel();
1071
+ const user = this.currentUser();
1072
+
1073
+ if (!channel || !user) return;
1074
+
1075
+ // Create message record (HTTP)
1076
+ this.createRecord({
1077
+ id: Date.now(), // Temporary ID
1078
+ content: message,
1079
+ channel: channel,
1080
+ userId: user.id,
1081
+ userName: user.name,
1082
+ timestamp: new Date()
1083
+ });
1084
+
1085
+ // Send via WebSocket
1086
+ this.store.sendMessage(
1087
+ {
1088
+ message: message,
1089
+ userId: user.id,
1090
+ userName: user.name,
1091
+ channel: channel
1092
+ },
1093
+ [channel]
1094
+ );
1095
+ }
1096
+
1097
+ getMessagesForChannel(channelName: string) {
1098
+ return this.store.data$.pipe(
1099
+ map(messages => messages.filter(msg => msg.channel === channelName))
1100
+ );
1101
+ }
1102
+ }
1103
+ ```
1104
+
1105
+ ### Complex Filter and Search State
1106
+
1107
+ ```typescript
1108
+ @Injectable()
1109
+ export class AdvancedUserStateService extends HTTPManagerStateService<User> {
1110
+
1111
+ // Filter state
1112
+ activeFilter = signal<'all' | 'active' | 'inactive'>('all');
1113
+ roleFilter = signal<string>('');
1114
+ searchQuery = signal<string>('');
1115
+ dateRange = signal<{start: Date, end: Date} | null>(null);
1116
+
1117
+ // Computed filters
1118
+ filteredUsers = computed(() => {
1119
+ let users = this.store.data$();
1120
+
1121
+ // Apply active filter
1122
+ if (this.activeFilter() !== 'all') {
1123
+ const isActive = this.activeFilter() === 'active';
1124
+ users = users.filter(user => user.active === isActive);
1125
+ }
1126
+
1127
+ // Apply role filter
1128
+ if (this.roleFilter()) {
1129
+ users = users.filter(user => user.role === this.roleFilter());
1130
+ }
1131
+
1132
+ // Apply search query
1133
+ if (this.searchQuery()) {
1134
+ const query = this.searchQuery().toLowerCase();
1135
+ users = users.filter(user =>
1136
+ user.name.toLowerCase().includes(query) ||
1137
+ user.email.toLowerCase().includes(query)
1138
+ );
1139
+ }
1140
+
1141
+ // Apply date range
1142
+ if (this.dateRange()) {
1143
+ const { start, end } = this.dateRange()!;
1144
+ users = users.filter(user => {
1145
+ const userDate = new Date(user.createdAt);
1146
+ return userDate >= start && userDate <= end;
1147
+ });
1148
+ }
1149
+
1150
+ return users;
1151
+ });
1152
+
1153
+ filterStats = computed(() => {
1154
+ const allUsers = this.store.data$();
1155
+ return {
1156
+ total: allUsers.length,
1157
+ active: allUsers.filter(u => u.active).length,
1158
+ inactive: allUsers.filter(u => !u.active).length,
1159
+ filtered: this.filteredUsers().length
1160
+ };
1161
+ });
1162
+
1163
+ constructor() {
1164
+ super(
1165
+ ApiRequest.adapt({
1166
+ server: 'http://localhost:8080',
1167
+ path: ['users'],
1168
+ adapter: User.adapt
1169
+ }),
1170
+ DataType.ARRAY,
1171
+ DatabaseStorage.adapt({
1172
+ table: 'users-advanced-cache',
1173
+ expiresIn: '1h'
1174
+ })
1175
+ );
1176
+ }
1177
+
1178
+ // Filter methods
1179
+ setActiveFilter(filter: 'all' | 'active' | 'inactive') {
1180
+ this.activeFilter.set(filter);
1181
+ this.fetchRecords();
1182
+ }
1183
+
1184
+ setRoleFilter(role: string) {
1185
+ this.roleFilter.set(role);
1186
+ this.fetchRecords();
1187
+ }
1188
+
1189
+ setSearchQuery(query: string) {
1190
+ this.searchQuery.set(query);
1191
+ // Debounced search
1192
+ setTimeout(() => this.fetchRecords(), 300);
1193
+ }
1194
+
1195
+ setDateRange(start: Date, end: Date) {
1196
+ this.dateRange.set({ start, end });
1197
+ this.fetchRecords();
1198
+ }
1199
+
1200
+ clearFilters() {
1201
+ this.activeFilter.set('all');
1202
+ this.roleFilter.set('');
1203
+ this.searchQuery.set('');
1204
+ this.dateRange.set(null);
1205
+ this.fetchRecords();
1206
+ }
1207
+ }
1208
+ ```
1209
+
1210
+ ## Error Handling and Retry Logic
1211
+
1212
+ ### Custom Error Handling
1213
+
1214
+ ```typescript
1215
+ @Injectable()
1216
+ export class RobustUserStateService extends HTTPManagerStateService<User> {
1217
+
1218
+ private retryAttempts = signal(0);
1219
+ private maxRetries = signal(3);
1220
+
1221
+ constructor() {
1222
+ super(
1223
+ ApiRequest.adapt({
1224
+ server: 'http://localhost:8080',
1225
+ path: ['users'],
1226
+ retry: { times: 3, delay: 2 },
1227
+ displayError: true
1228
+ }),
1229
+ DataType.ARRAY
1230
+ );
1231
+ }
1232
+
1233
+ // Override to add custom error handling
1234
+ fetchRecords(params?: any) {
1235
+ this.retryAttempts.set(0);
1236
+ super.fetchRecords(params);
1237
+ }
1238
+
1239
+ // Custom retry logic for critical operations
1240
+ criticalUpdate(user: User) {
1241
+ try {
1242
+ this.updateRecord(user);
1243
+ } catch (error) {
1244
+ this.handleCriticalError(error, () => this.criticalUpdate(user));
1245
+ }
1246
+ }
1247
+
1248
+ private handleCriticalError(error: any, retryFn: () => void) {
1249
+ const currentAttempts = this.retryAttempts();
1250
+ const maxAttempts = this.maxRetries();
1251
+
1252
+ if (currentAttempts < maxAttempts) {
1253
+ this.retryAttempts.set(currentAttempts + 1);
1254
+
1255
+ // Exponential backoff
1256
+ const delay = Math.pow(2, currentAttempts) * 1000;
1257
+ setTimeout(retryFn, delay);
1258
+ } else {
1259
+ // Max retries reached, show critical error
1260
+ this.showCriticalErrorDialog(error);
1261
+ }
1262
+ }
1263
+
1264
+ private showCriticalErrorDialog(error: any) {
1265
+ // Implement your critical error handling
1266
+ console.error('Critical operation failed after retries:', error);
1267
+ }
1268
+ }
1269
+ ```
1270
+
1271
+ ## Best Practices
1272
+
1273
+ ### 1. Service Layer Pattern
1274
+
1275
+ ```typescript
1276
+ // ✅ Good
1277
+ @Injectable()
1278
+ export class UserStateService extends HTTPManagerStateService<User> {
1279
+ // Business logic methods
1280
+ activateUser(id: number) {
1281
+ this.updateRecord({ id, active: true });
1282
+ }
1283
+
1284
+ deactivateUser(id: number) {
1285
+ this.updateRecord({ id, active: false });
1286
+ }
1287
+ }
1288
+
1289
+ // ❌ Avoid
1290
+ @Component({
1291
+ template: `<div (click)="store.updateRecord(...)">`
1292
+ })
1293
+ export class BadComponent {}
1294
+ ```
1295
+
1296
+ ### 2. Proper State Management
1297
+
1298
+ ```typescript
1299
+ // ✅ Good
1300
+ loadUsers() {
1301
+ this.fetchRecords(); // Uses internal state management
1302
+ }
1303
+
1304
+ // ❌ Avoid
1305
+ loadUsers() {
1306
+ this.http.get('users').subscribe(users => {
1307
+ this.users = users; // Manual state management
1308
+ });
1309
+ }
1310
+ ```
1311
+
1312
+ ### 3. WebSocket Error Handling
1313
+
1314
+ ```typescript
1315
+ // ✅ Good
1316
+ initializeConnection(wsServer: string, jwtToken: string, user: any) {
1317
+ try {
1318
+ this.setApiRequestOptions(
1319
+ ApiRequest.adapt({
1320
+ ...this.apiRequestOptions,
1321
+ ws: { ...this.apiRequestOptions.ws, wsServer, jwtToken, user }
1322
+ })
1323
+ );
1324
+ } catch (error) {
1325
+ console.error('WebSocket initialization failed:', error);
1326
+ }
1327
+ }
1328
+ ```
1329
+
1330
+ ### 4. Memory Management
1331
+
1332
+ ```typescript
1333
+ @Component({ template: '...' })
1334
+ export class UserComponent implements OnDestroy {
1335
+ private destroy$ = new Subject<void>();
1336
+
1337
+ ngOnInit() {
1338
+ this.store.data$
1339
+ .pipe(takeUntil(this.destroy$))
1340
+ .subscribe();
1341
+ }
1342
+
1343
+ ngOnDestroy() {
1344
+ this.destroy$.next();
1345
+ this.destroy$.complete();
1346
+ }
1347
+ }
1348
+ ```
1349
+
1350
+ ## Troubleshooting
1351
+
1352
+ ### Common Issues
1353
+
1354
+ #### 1. WebSocket Not Connecting
1355
+ ```typescript
1356
+ // Check configuration
1357
+ console.log('WS Config:', this.store.apiRequestOptions?.ws);
1358
+
1359
+ // Verify connection
1360
+ this.store.connectionStatus$.subscribe(status => {
1361
+ console.log('WebSocket status:', status);
1362
+ });
1363
+ ```
1364
+
1365
+ #### 2. State Not Updating
1366
+ ```typescript
1367
+ // Ensure adapter is provided for database storage
1368
+ ApiRequest.adapt({
1369
+ path: ['users'],
1370
+ adapter: User.adapt // Required!
1371
+ });
1372
+ ```
1373
+
1374
+ #### 3. Infinite Loops
1375
+ ```typescript
1376
+ // Avoid calling fetchRecords() in response to WebSocket messages
1377
+ // The service handles this automatically
1378
+
1379
+ // ❌ Don't do this
1380
+ communicationMessages$.subscribe(msg => {
1381
+ this.fetchRecords(); // This can cause loops
1382
+ });
1383
+ ```
1384
+
1385
+ ## Related Documentation
1386
+
1387
+ - [HTTP Manager Service](http-manager/README.md)
1388
+ - [HTTP Signals Service](http-signals/README.md)
1389
+ - [WebSocket Service](websocket/README.md)
1390
+ - [Database Manager Service](database/README.md)
1391
+ - [Architecture Overview](../architecture/README.md)