http-request-manager 18.15.32 → 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 (301) hide show
  1. package/README.md +2 -0
  2. package/TEST_COVERAGE_SUMMARY.md +458 -0
  3. package/ng-package.json +8 -0
  4. package/package.json +5 -13
  5. package/src/docs/ADVANCED_WEBSOCKET.md +633 -0
  6. package/src/docs/ARCHITECTURE.md +633 -0
  7. package/src/docs/BATCH_REQUEST_README.md +467 -0
  8. package/src/docs/COMPLETE_API_REFERENCE.md +1037 -0
  9. package/src/docs/DATABASE_README.md +1195 -0
  10. package/src/docs/ENCRYPTION_README.md +403 -0
  11. package/src/docs/HTTP_MANAGER_README.md +628 -0
  12. package/src/docs/HTTP_SINGNALS_MANAGER_README.md +654 -0
  13. package/src/docs/HTTP_STATE_MANAGER_README.md +1391 -0
  14. package/src/docs/INTERCEPTOR_README.md +549 -0
  15. package/src/docs/LOCAL_STORAGE_README.md +1056 -0
  16. package/src/docs/LOCAL_STORAGE_SIGNALS_README.md +338 -0
  17. package/src/docs/LOGGER_README.md +310 -0
  18. package/src/docs/MESSAGE_TRACKER_README.md +518 -0
  19. package/src/docs/MESSAGE_TRACKER_SIGNALS_README.md +563 -0
  20. package/src/docs/MODELS_README.md +1264 -0
  21. package/src/docs/SIGNAL_SERVICES_README.md +238 -0
  22. package/src/docs/SQL_DIXIE_README.md +574 -0
  23. package/src/docs/STORE_STATE_MANAGER_README.md +556 -0
  24. package/src/docs/STORE_STATE_SIGNALS_README.md +600 -0
  25. package/src/docs/UPLOAD_REQUEST_README.md +324 -0
  26. package/src/docs/UTILS_README.md +1604 -0
  27. package/src/docs/WEBSOCKET_MESSAGE_SERVICE.md +799 -0
  28. package/src/docs/WEBSOCKET_SIGNALS_README.md +641 -0
  29. package/src/docs/WEBSOCKET_SINGLETON_REFACTORING.md +201 -0
  30. package/src/docs/WS_MANAGER_README.md +613 -0
  31. package/src/lib/http-request-manager.module.ts +147 -0
  32. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.html +116 -0
  33. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.scss +0 -0
  34. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.ts +255 -0
  35. package/src/lib/http-request-services-demo/http-request-services-demo.component.html +123 -0
  36. package/src/lib/http-request-services-demo/http-request-services-demo.component.scss +6 -0
  37. package/src/lib/http-request-services-demo/http-request-services-demo.component.ts +53 -0
  38. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.html +195 -0
  39. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.scss +17 -0
  40. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.ts +208 -0
  41. package/src/lib/http-request-services-demo/local-storage-signals-demo/local-storage-signals-demo.component.html +200 -0
  42. package/src/lib/http-request-services-demo/local-storage-signals-demo/local-storage-signals-demo.component.scss +17 -0
  43. package/src/lib/http-request-services-demo/local-storage-signals-demo/local-storage-signals-demo.component.ts +214 -0
  44. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/download-file/download-file.component.html +53 -0
  45. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/download-file/download-file.component.scss +60 -0
  46. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/download-file/download-file.component.ts +72 -0
  47. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/file-download.module.ts +28 -0
  48. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/file-downloader.component.html +10 -0
  49. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/file-downloader.component.scss +29 -0
  50. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/file-downloader.component.ts +100 -0
  51. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/models/download-labels-model.ts +22 -0
  52. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/spinner/spinner.component.html +8 -0
  53. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/spinner/spinner.component.scss +19 -0
  54. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/spinner/spinner.component.ts +26 -0
  55. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/app-session.model.ts +30 -0
  56. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/app.model.ts +19 -0
  57. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/get-sample.model.ts +25 -0
  58. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-ai-prompt.ts +19 -0
  59. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-client-details.ts +24 -0
  60. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-client-info.ts +30 -0
  61. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-client.model.ts +49 -0
  62. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-mapper-client-info.ts +33 -0
  63. package/src/lib/http-request-services-demo/request-manager-basic-demo/request-manager-basic-demo.component.html +279 -0
  64. package/src/lib/http-request-services-demo/request-manager-basic-demo/request-manager-basic-demo.component.scss +24 -0
  65. package/src/lib/http-request-services-demo/request-manager-basic-demo/request-manager-basic-demo.component.ts +461 -0
  66. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.html +53 -0
  67. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.scss +60 -0
  68. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.ts +72 -0
  69. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-download.module.ts +28 -0
  70. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.html +10 -0
  71. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.scss +29 -0
  72. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.ts +100 -0
  73. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/models/download-labels-model.ts +22 -0
  74. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.html +8 -0
  75. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.scss +19 -0
  76. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.ts +26 -0
  77. package/src/lib/http-request-services-demo/request-manager-demo/models/app-session.model.ts +30 -0
  78. package/src/lib/http-request-services-demo/request-manager-demo/models/app.model.ts +19 -0
  79. package/src/lib/http-request-services-demo/request-manager-demo/models/get-sample.model.ts +25 -0
  80. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-ai-prompt.ts +19 -0
  81. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client-details.ts +24 -0
  82. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client-info.ts +30 -0
  83. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client.model.ts +49 -0
  84. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-mapper-client-info.ts +33 -0
  85. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.html +622 -0
  86. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.scss +106 -0
  87. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.ts +687 -0
  88. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.html +418 -0
  89. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.scss +24 -0
  90. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.ts +576 -0
  91. package/src/lib/http-request-services-demo/request-manager-state-demo/services/state-manager-demo.service.ts +89 -0
  92. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/services/state-data-request.service.ts +119 -0
  93. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-ai-messaging/ws-ai-messaging.component.css +0 -0
  94. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-ai-messaging/ws-ai-messaging.component.html +3 -0
  95. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-ai-messaging/ws-ai-messaging.component.ts +16 -0
  96. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-chats/ws-chats.component.css +0 -0
  97. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-chats/ws-chats.component.html +3 -0
  98. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-chats/ws-chats.component.ts +16 -0
  99. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.css +31 -0
  100. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.html +94 -0
  101. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.scss +41 -0
  102. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.spec.ts +203 -0
  103. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.ts +144 -0
  104. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.css +11 -0
  105. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.html +102 -0
  106. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.spec.ts +40 -0
  107. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.ts +230 -0
  108. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.css +30 -0
  109. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.html +172 -0
  110. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.spec.ts +31 -0
  111. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.ts +239 -0
  112. package/src/lib/http-request-services-demo/request-manager-ws-demo/models/oidc-client.model.ts +31 -0
  113. package/src/lib/http-request-services-demo/request-manager-ws-demo/models/user-data.model.ts +32 -0
  114. package/src/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.css +0 -0
  115. package/src/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.html +84 -0
  116. package/src/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.ts +40 -0
  117. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/index.ts +3 -0
  118. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/jwt-token.service.ts +62 -0
  119. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/message-service-demo.service.ts +83 -0
  120. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/notification-service-demo.service.ts +147 -0
  121. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/state-service-demo.service.ts +168 -0
  122. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/download-file/download-file.component.html +53 -0
  123. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/download-file/download-file.component.scss +60 -0
  124. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/download-file/download-file.component.ts +72 -0
  125. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-download.module.ts +28 -0
  126. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-downloader.component.html +10 -0
  127. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-downloader.component.scss +29 -0
  128. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-downloader.component.ts +100 -0
  129. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/models/download-labels-model.ts +22 -0
  130. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/spinner/spinner.component.html +8 -0
  131. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/spinner/spinner.component.scss +19 -0
  132. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/spinner/spinner.component.ts +26 -0
  133. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/app-session.model.ts +30 -0
  134. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/app.model.ts +19 -0
  135. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/get-sample.model.ts +25 -0
  136. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-ai-prompt.ts +19 -0
  137. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-client-details.ts +24 -0
  138. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-client-info.ts +30 -0
  139. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-client.model.ts +49 -0
  140. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-mapper-client-info.ts +33 -0
  141. package/src/lib/http-request-services-demo/request-signals-manager-demo/request-signals-manager-demo.component.html +380 -0
  142. package/src/lib/http-request-services-demo/request-signals-manager-demo/request-signals-manager-demo.component.scss +24 -0
  143. package/src/lib/http-request-services-demo/request-signals-manager-demo/request-signals-manager-demo.component.ts +410 -0
  144. package/src/lib/http-request-services-demo/store-state-manager-demo/models/settings.model.ts +28 -0
  145. package/src/lib/http-request-services-demo/store-state-manager-demo/services/settings-state.service.ts +49 -0
  146. package/src/lib/http-request-services-demo/store-state-manager-demo/store-state-manager-demo.component.css +0 -0
  147. package/src/lib/http-request-services-demo/store-state-manager-demo/store-state-manager-demo.component.html +23 -0
  148. package/src/lib/http-request-services-demo/store-state-manager-demo/store-state-manager-demo.component.ts +36 -0
  149. package/src/lib/http-request-services-demo/store-state-signals-demo/store-state-signals-demo.component.ts +161 -0
  150. package/src/lib/http-request-services-demo/upload-demo/models/index.ts +1 -0
  151. package/src/lib/http-request-services-demo/upload-demo/models/upload-state.model.ts +30 -0
  152. package/src/lib/http-request-services-demo/upload-demo/upload-demo.component.html +89 -0
  153. package/src/lib/http-request-services-demo/upload-demo/upload-demo.component.scss +160 -0
  154. package/src/lib/http-request-services-demo/upload-demo/upload-demo.component.spec.ts +101 -0
  155. package/src/lib/http-request-services-demo/upload-demo/upload-demo.component.ts +136 -0
  156. package/src/lib/index.ts +3 -0
  157. package/src/lib/interceptors/credentials.interceptor.ts +16 -0
  158. package/src/lib/interceptors/index.ts +6 -0
  159. package/src/lib/interceptors/models/error-settings.model.ts +22 -0
  160. package/src/lib/interceptors/models/index.ts +2 -0
  161. package/src/lib/interceptors/proxy-debugger.interceptor.ts +46 -0
  162. package/src/lib/interceptors/request-error.interceptor.ts +65 -0
  163. package/src/lib/interceptors/request-header.interceptor.ts +56 -0
  164. package/src/lib/message-display/README.md +509 -0
  165. package/src/lib/message-display/index.ts +4 -0
  166. package/src/lib/message-display/models/action.model.ts +27 -0
  167. package/src/lib/message-display/models/communication-message.model.ts +77 -0
  168. package/src/lib/message-display/models/display-config.model.ts +35 -0
  169. package/src/lib/message-display/models/display-rule.interface.ts +28 -0
  170. package/src/lib/message-display/models/display-strategy.interface.ts +8 -0
  171. package/src/lib/message-display/models/index.ts +6 -0
  172. package/src/lib/message-display/models/slide.model.ts +24 -0
  173. package/src/lib/message-display/rules/default-display-rules.ts +35 -0
  174. package/src/lib/message-display/services/message-display-router.service.ts +63 -0
  175. package/src/lib/message-display/strategies/snackbar.strategy.ts +46 -0
  176. package/src/lib/models/batch-options.model.ts +33 -0
  177. package/src/lib/models/batch-progress.model.ts +19 -0
  178. package/src/lib/models/batch-request-state.model.ts +40 -0
  179. package/src/lib/models/batch-result.model.ts +30 -0
  180. package/src/lib/models/config-http-options.model.ts +45 -0
  181. package/src/lib/models/config-local-storage-options.model.ts +27 -0
  182. package/src/lib/models/config-options.model.ts +27 -0
  183. package/src/lib/models/config-token.model.ts +9 -0
  184. package/src/lib/models/data-type.enum.ts +5 -0
  185. package/src/lib/models/database-storage.model.ts +24 -0
  186. package/src/lib/models/index.ts +16 -0
  187. package/src/lib/models/retry-options.model.ts +22 -0
  188. package/src/lib/models/upload-validation-error.model.ts +46 -0
  189. package/src/lib/services/SQL-DixieJS service/dexie-query-executor.ts +246 -0
  190. package/src/lib/services/SQL-DixieJS service/dexie-sql.service.ts +31 -0
  191. package/src/lib/services/SQL-DixieJS service/index.ts +4 -0
  192. package/src/lib/services/SQL-DixieJS service/models/execution-plan.model.ts +52 -0
  193. package/src/lib/services/SQL-DixieJS service/models/index.ts +3 -0
  194. package/src/lib/services/SQL-DixieJS service/models/sql-errors.model.ts +13 -0
  195. package/src/lib/services/SQL-DixieJS service/models/sql-options.model.ts +3 -0
  196. package/src/lib/services/SQL-DixieJS service/query-planner.ts +284 -0
  197. package/src/lib/services/SQL-DixieJS service/schema-validator.ts +217 -0
  198. package/src/lib/services/SQL-DixieJS service/sql-parser.ts +35 -0
  199. package/src/lib/services/database-manager-service/database.manager.service.ts +384 -0
  200. package/src/lib/services/database-manager-service/db.storage.service.ts +240 -0
  201. package/src/lib/services/database-manager-service/index.ts +4 -0
  202. package/src/lib/services/database-manager-service/models/index.ts +2 -0
  203. package/src/lib/services/database-manager-service/models/table-schema.ts +33 -0
  204. package/src/lib/services/index.ts +20 -0
  205. package/src/lib/services/local-storage-manager-service/index.ts +4 -0
  206. package/src/lib/services/local-storage-manager-service/local-storage-manager.service.spec.ts +71 -0
  207. package/src/lib/services/local-storage-manager-service/local-storage-manager.service.ts +567 -0
  208. package/src/lib/services/local-storage-manager-service/local-storage-signals-manager.service.spec.ts +67 -0
  209. package/src/lib/services/local-storage-manager-service/local-storage-signals-manager.service.ts +437 -0
  210. package/src/lib/services/local-storage-manager-service/models/global-store-options.model.ts +30 -0
  211. package/src/lib/services/local-storage-manager-service/models/index.ts +6 -0
  212. package/src/lib/services/local-storage-manager-service/models/setting-options.model.ts +35 -0
  213. package/src/lib/services/local-storage-manager-service/models/storage-data.model.ts +24 -0
  214. package/src/lib/services/local-storage-manager-service/models/storage-option.model.ts +32 -0
  215. package/src/lib/services/local-storage-manager-service/models/storage-type.enum.ts +5 -0
  216. package/src/lib/services/request-manager-services/README.md +282 -0
  217. package/src/lib/services/request-manager-services/http-manager-signals.service.ts +674 -0
  218. package/src/lib/services/request-manager-services/http-manager.service.spec.ts +353 -0
  219. package/src/lib/services/request-manager-services/http-manager.service.ts +727 -0
  220. package/src/lib/services/request-manager-services/index.ts +8 -0
  221. package/src/lib/services/request-manager-services/request-signals.service.ts +372 -0
  222. package/src/lib/services/request-manager-services/request.service.ts +435 -0
  223. package/src/lib/services/request-manager-services/rxjs-operators/countdown.ts +17 -0
  224. package/src/lib/services/request-manager-services/rxjs-operators/delay-retry.ts +16 -0
  225. package/src/lib/services/request-manager-services/rxjs-operators/index.ts +4 -0
  226. package/src/lib/services/request-manager-services/rxjs-operators/request-polling.ts +35 -0
  227. package/src/lib/services/request-manager-services/rxjs-operators/request-streaming.ts +468 -0
  228. package/src/lib/services/request-manager-state-service/http-manager-state.store.spec.ts +665 -0
  229. package/src/lib/services/request-manager-state-service/http-manager-state.store.ts +2395 -0
  230. package/src/lib/services/request-manager-state-service/index.ts +3 -0
  231. package/src/lib/services/request-manager-state-service/models/api-request.model.ts +86 -0
  232. package/src/lib/services/request-manager-state-service/models/index.ts +14 -0
  233. package/src/lib/services/request-manager-state-service/models/operation-result.model.ts +18 -0
  234. package/src/lib/services/request-manager-state-service/models/parsing-result.model.ts +21 -0
  235. package/src/lib/services/request-manager-state-service/models/request-options.model.ts +37 -0
  236. package/src/lib/services/request-manager-state-service/models/stream-config.model.ts +20 -0
  237. package/src/lib/services/request-manager-state-service/models/stream-event-metadata.model.ts +23 -0
  238. package/src/lib/services/request-manager-state-service/models/stream-event.model.ts +23 -0
  239. package/src/lib/services/request-manager-state-service/models/stream-output.model.ts +23 -0
  240. package/src/lib/services/request-manager-state-service/models/stream-progress.model.ts +24 -0
  241. package/src/lib/services/request-manager-state-service/models/stream-type.enum.ts +13 -0
  242. package/src/lib/services/request-manager-state-service/models/ws-options.model.ts +42 -0
  243. package/src/lib/services/store-state-manager-service/index.ts +4 -0
  244. package/src/lib/services/store-state-manager-service/models/index.ts +3 -0
  245. package/src/lib/services/store-state-manager-service/models/state-operation-result.model.ts +30 -0
  246. package/src/lib/services/store-state-manager-service/models/state-storage-options.model.ts +24 -0
  247. package/src/lib/services/store-state-manager-service/store-state-manager-signals.service.ts +169 -0
  248. package/src/lib/services/store-state-manager-service/store-state-manager.service.ts +153 -0
  249. package/src/lib/services/utils/app.service.spec.ts +25 -0
  250. package/src/lib/services/utils/app.service.ts +21 -0
  251. package/src/lib/services/utils/encryption/README.md +79 -0
  252. package/src/lib/services/utils/encryption/asymmetrical-encryption.service.ts +282 -0
  253. package/src/lib/services/utils/encryption/encryption-test.service.ts +39 -0
  254. package/src/lib/services/utils/encryption/index.ts +5 -0
  255. package/src/lib/services/utils/encryption/random.ts +81 -0
  256. package/src/lib/services/utils/encryption/symmetrical-encryption.service.ts +106 -0
  257. package/src/lib/services/utils/headers.service.spec.ts +80 -0
  258. package/src/lib/services/utils/headers.service.ts +18 -0
  259. package/src/lib/services/utils/index.ts +9 -0
  260. package/src/lib/services/utils/logger.service.ts +90 -0
  261. package/src/lib/services/utils/models/index.ts +4 -0
  262. package/src/lib/services/utils/models/normalized-request-options.model.ts +24 -0
  263. package/src/lib/services/utils/models/path-tracker-state.model.ts +20 -0
  264. package/src/lib/services/utils/models/query-params-tracker-options.model.ts +24 -0
  265. package/src/lib/services/utils/models/query-tracker-state.model.ts +23 -0
  266. package/src/lib/services/utils/object-merger.service.spec.ts +18 -0
  267. package/src/lib/services/utils/object-merger.service.ts +78 -0
  268. package/src/lib/services/utils/path-query.service.spec.ts +117 -0
  269. package/src/lib/services/utils/path-query.service.ts +69 -0
  270. package/src/lib/services/utils/query-params-tracker.service.ts +442 -0
  271. package/src/lib/services/utils/random-color.utils.ts +83 -0
  272. package/src/lib/services/utils/utils.service.spec.ts +165 -0
  273. package/src/lib/services/utils/utils.service.ts +192 -0
  274. package/src/lib/services/ws-manager-service/index.ts +13 -0
  275. package/src/lib/services/ws-manager-service/message-tracker-signals.service.ts +147 -0
  276. package/src/lib/services/ws-manager-service/message-tracker.service.ts +477 -0
  277. package/src/lib/services/ws-manager-service/models/channel-info.model.ts +29 -0
  278. package/src/lib/services/ws-manager-service/models/channel-message-data.model.ts +24 -0
  279. package/src/lib/services/ws-manager-service/models/channel-message.model.ts +36 -0
  280. package/src/lib/services/ws-manager-service/models/channel-type.enum.ts +6 -0
  281. package/src/lib/services/ws-manager-service/models/communication-type.enum.ts +5 -0
  282. package/src/lib/services/ws-manager-service/models/index.ts +10 -0
  283. package/src/lib/services/ws-manager-service/models/notification-message.model.ts +29 -0
  284. package/src/lib/services/ws-manager-service/models/public-message.model.ts +18 -0
  285. package/src/lib/services/ws-manager-service/models/state-message.model.ts +18 -0
  286. package/src/lib/services/ws-manager-service/models/ws-user.model.ts +38 -0
  287. package/src/lib/services/ws-manager-service/services/index.ts +4 -0
  288. package/src/lib/services/ws-manager-service/services/websocket-message.service.ts +129 -0
  289. package/src/lib/services/ws-manager-service/services/websocket.service.ts +434 -0
  290. package/src/lib/services/ws-manager-service/websocket-service/index.ts +1 -0
  291. package/src/lib/services/ws-manager-service/websocket-service/websocket-manager.service.ts +716 -0
  292. package/src/lib/services/ws-manager-service/websocket-services-complete.spec.ts +596 -0
  293. package/src/lib/services/ws-manager-service/websocket-signals-manager.service.ts +141 -0
  294. package/src/public-api.ts +19 -0
  295. package/tsconfig.lib.json +34 -0
  296. package/tsconfig.lib.prod.json +10 -0
  297. package/tsconfig.spec.json +14 -0
  298. package/fesm2022/http-request-manager.mjs +0 -13297
  299. package/fesm2022/http-request-manager.mjs.map +0 -1
  300. package/http-request-manager-18.15.32.tgz +0 -0
  301. package/types/http-request-manager.d.ts +0 -3875
@@ -0,0 +1,1195 @@
1
+ # Database Manager Service
2
+
3
+ The `DatabaseManagerService` is a wrapper service for Dexie.js that provides IndexedDB interactions using RxJS Observables. It enables offline-first applications with sophisticated local data storage and querying capabilities.
4
+
5
+ ## Overview
6
+
7
+ This service provides:
8
+
9
+ - **IndexedDB Management** - Complete wrapper around Dexie.js for IndexedDB operations
10
+ - **Observable API** - All operations return Observables for reactive programming
11
+ - **Table Management** - Create and manage database tables with flexible schemas
12
+ - **CRUD Operations** - Full support for Create, Read, Update, Delete operations
13
+ - **Querying** - Advanced querying capabilities with filtering and sorting
14
+ - **Bulk Operations** - Optimized methods for batch operations
15
+ - **Schema Inspection** - Check table existence and retrieve schema definitions
16
+
17
+ ## Installation
18
+
19
+ ```typescript
20
+ import { HttpRequestManagerModule } from 'http-request-manager';
21
+
22
+ @NgModule({
23
+ imports: [HttpRequestManagerModule.forRoot({})]
24
+ })
25
+ export class AppModule { }
26
+ ```
27
+
28
+ ## Basic Usage
29
+
30
+ ### Service Injection
31
+
32
+ ```typescript
33
+ import { Component, inject } from '@angular/core';
34
+ import { DatabaseManagerService, TableSchemaDef } from 'http-request-manager';
35
+
36
+ @Component({
37
+ selector: 'app-database-demo',
38
+ template: `
39
+ <div class="database-demo">
40
+ <h2>Database Operations Demo</h2>
41
+
42
+ <div class="actions">
43
+ <button (click)="initializeTables()">Initialize Tables</button>
44
+ <button (click)="addSampleData()">Add Sample Data</button>
45
+ <button (click)="loadData()">Load Data</button>
46
+ <button (click)="clearData()">Clear All</button>
47
+ </div>
48
+
49
+ <div class="status">
50
+ <p>Loading: {{ isLoading ? 'Yes' : 'No' }}</p>
51
+ <p>Table Status: {{ tableStatus }}</p>
52
+ </div>
53
+
54
+ <div class="data-display" *ngIf="data.length > 0">
55
+ <h3>Stored Data ({{ data.length }} records)</h3>
56
+ <div *ngFor="let item of data" class="data-item">
57
+ <strong>{{ item.name }}</strong> - {{ item.email }}
58
+ <button (click)="deleteItem(item.id)">Delete</button>
59
+ </div>
60
+ </div>
61
+
62
+ <div class="search-section">
63
+ <h3>Search</h3>
64
+ <input [(ngModel)]="searchQuery" placeholder="Search by name...">
65
+ <button (click)="search()">Search</button>
66
+ <div *ngFor="let result of searchResults" class="search-result">
67
+ {{ result.name }} - {{ result.email }}
68
+ </div>
69
+ </div>
70
+ </div>
71
+ `
72
+ })
73
+ export class DatabaseDemoComponent {
74
+ private dbManager = inject(DatabaseManagerService);
75
+
76
+ data: any[] = [];
77
+ searchResults: any[] = [];
78
+ searchQuery = '';
79
+ isLoading = false;
80
+ tableStatus = 'Not initialized';
81
+
82
+ initializeTables() {
83
+ const tableDef = TableSchemaDef.adapt({
84
+ table: 'users',
85
+ schema: '++id, name, email, age, createdAt'
86
+ });
87
+
88
+ this.dbManager.createDatabaseTable(tableDef).subscribe({
89
+ next: () => {
90
+ this.tableStatus = 'Table created successfully';
91
+ console.log('Users table initialized');
92
+ },
93
+ error: (error) => {
94
+ this.tableStatus = `Error: ${error.message}`;
95
+ console.error('Table creation failed:', error);
96
+ }
97
+ });
98
+ }
99
+
100
+ addSampleData() {
101
+ const users = [
102
+ { name: 'John Doe', email: 'john@example.com', age: 30, createdAt: new Date() },
103
+ { name: 'Jane Smith', email: 'jane@example.com', age: 25, createdAt: new Date() },
104
+ { name: 'Bob Johnson', email: 'bob@example.com', age: 35, createdAt: new Date() }
105
+ ];
106
+
107
+ this.dbManager.createTableRecords('users', users).subscribe({
108
+ next: () => {
109
+ console.log('Sample data added');
110
+ this.loadData();
111
+ },
112
+ error: (error) => console.error('Failed to add data:', error)
113
+ });
114
+ }
115
+
116
+ loadData() {
117
+ this.isLoading = true;
118
+ this.dbManager.getTableRecords('users').subscribe({
119
+ next: (users) => {
120
+ this.data = users;
121
+ this.isLoading = false;
122
+ console.log('Data loaded:', users);
123
+ },
124
+ error: (error) => {
125
+ console.error('Failed to load data:', error);
126
+ this.isLoading = false;
127
+ }
128
+ });
129
+ }
130
+
131
+ deleteItem(id: number) {
132
+ this.dbManager.deleteTableRecord('users', id).subscribe({
133
+ next: () => {
134
+ console.log('Record deleted');
135
+ this.loadData();
136
+ },
137
+ error: (error) => console.error('Delete failed:', error)
138
+ });
139
+ }
140
+
141
+ search() {
142
+ if (this.searchQuery.trim()) {
143
+ this.dbManager.findTableRecords('users', 'name', this.searchQuery).subscribe({
144
+ next: (results) => {
145
+ this.searchResults = results;
146
+ console.log('Search results:', results);
147
+ },
148
+ error: (error) => console.error('Search failed:', error)
149
+ });
150
+ }
151
+ }
152
+
153
+ clearData() {
154
+ // Clear only the 'users' table (Observable - subscribe to complete)
155
+ this.dbManager.clearTable('users').subscribe({
156
+ next: () => {
157
+ this.data = [];
158
+ this.searchResults = [];
159
+ console.log('All user records cleared');
160
+ },
161
+ error: (error) => console.error('Clear failed:', error)
162
+ });
163
+ }
164
+ }
165
+ ```
166
+
167
+ // To wipe the entire IndexedDB and clear the library's localStorage metadata (query trackers, expirations, etc.), call:
168
+
169
+ ```typescript
170
+ // Fire-and-forget - subscription handled internally
171
+ this.dbManager.clearDatabase();
172
+ ```
173
+
174
+ This will delete the DB, clear the in-memory state and also invoke `LocalStorageManagerService.clearAllStoredData()` to remove metadata stored in localStorage.
175
+
176
+ Service to use for these operations:
177
+
178
+ - **`DatabaseManagerService`** — provides table-level CRUD and maintenance methods (`createTableRecords`, `getTableRecords`, `clearTable`, `deleteTableRecord`, etc.) and a convenience `clearDatabase()` method which wipes the whole DB and related localStorage metadata.
179
+
180
+ Notes:
181
+
182
+ - `clearDatabase()` subscribes internally and is fire-and-forget. Call it directly with `this.dbManager.clearDatabase()` (no `.subscribe()` required).
183
+ - Table-level methods such as `clearTable(table)` return `Observable`s and should be subscribed to by callers when they need to react to completion.
184
+
185
+ ## API Reference
186
+
187
+ ### Table Management
188
+
189
+ #### createDatabaseTable(tableDef: TableSchemaDef): Observable<void>
190
+
191
+ Create a new database table:
192
+
193
+ ```typescript
194
+ const tableDef = TableSchemaDef.adapt({
195
+ table: 'products',
196
+ schema: '++id, name, price, category, createdAt'
197
+ });
198
+
199
+ this.dbManager.createDatabaseTable(tableDef).subscribe(() => {
200
+ console.log('Products table created');
201
+ });
202
+ ```
203
+
204
+ #### hasDatabaseTable(tableName: string): Observable<boolean>
205
+
206
+ Check if table exists:
207
+
208
+ ```typescript
209
+ this.dbManager.hasDatabaseTable('users').subscribe(exists => {
210
+ if (exists) {
211
+ console.log('Users table exists');
212
+ } else {
213
+ console.log('Users table does not exist');
214
+ }
215
+ });
216
+ ```
217
+
218
+ #### getTableSchema(tableName: string): Observable<any>
219
+
220
+ Get table schema definition:
221
+
222
+ ```typescript
223
+ this.dbManager.getTableSchema('users').subscribe(schema => {
224
+ console.log('Table schema:', schema);
225
+ });
226
+ ```
227
+
228
+ ### CRUD Operations
229
+
230
+ #### createTableRecord(tableName: string, data: any): Observable<any>
231
+
232
+ Create a single record:
233
+
234
+ ```typescript
235
+ this.dbManager.createTableRecord('users', {
236
+ name: 'John Doe',
237
+ email: 'john@example.com',
238
+ age: 30
239
+ }).subscribe(createdRecord => {
240
+ console.log('Record created with ID:', createdRecord.id);
241
+ });
242
+ ```
243
+
244
+ #### createTableRecords(tableName: string, dataArray: any[]): Observable<any[]>
245
+
246
+ Create multiple records:
247
+
248
+ ```typescript
249
+ const users = [
250
+ { name: 'John Doe', email: 'john@example.com', age: 30 },
251
+ { name: 'Jane Smith', email: 'jane@example.com', age: 25 },
252
+ { name: 'Bob Johnson', email: 'bob@example.com', age: 35 }
253
+ ];
254
+
255
+ this.dbManager.createTableRecords('users', users).subscribe(createdRecords => {
256
+ console.log('Created', createdRecords.length, 'records');
257
+ });
258
+ ```
259
+
260
+ #### getTableRecords(tableName: string): Observable<any[]>
261
+
262
+ Get all records from a table:
263
+
264
+ ```typescript
265
+ this.dbManager.getTableRecords('users').subscribe(users => {
266
+ console.log('All users:', users);
267
+ });
268
+ ```
269
+
270
+ #### getTableRecord(tableName: string, id: any): Observable<any>
271
+
272
+ Get a specific record by ID:
273
+
274
+ ```typescript
275
+ this.dbManager.getTableRecord('users', 1).subscribe(user => {
276
+ console.log('User with ID 1:', user);
277
+ });
278
+ ```
279
+
280
+ #### updateTableRecord(tableName: string, data: any): Observable<any>
281
+
282
+ Update an existing record:
283
+
284
+ ```typescript
285
+ this.dbManager.updateTableRecord('users', {
286
+ id: 1,
287
+ name: 'John Smith',
288
+ email: 'john.smith@example.com',
289
+ age: 31
290
+ }).subscribe(updatedRecord => {
291
+ console.log('Updated record:', updatedRecord);
292
+ });
293
+ ```
294
+
295
+ #### deleteTableRecord(tableName: string, id: any): Observable<void>
296
+
297
+ Delete a record by ID:
298
+
299
+ ```typescript
300
+ this.dbManager.deleteTableRecord('users', 1).subscribe(() => {
301
+ console.log('Record deleted');
302
+ });
303
+ ```
304
+
305
+ ### Querying Operations
306
+
307
+ #### findTableRecords(tableName: string, field: string, value: any): Observable<any[]>
308
+
309
+ Find records by field value:
310
+
311
+ ```typescript
312
+ // Find users by age
313
+ this.dbManager.findTableRecords('users', 'age', 30).subscribe(users => {
314
+ console.log('Users aged 30:', users);
315
+ });
316
+
317
+ // Find users by name (partial match)
318
+ this.dbManager.findTableRecords('users', 'name', 'John').subscribe(users => {
319
+ console.log('Users with "John" in name:', users);
320
+ });
321
+ ```
322
+
323
+ #### queryTableRecords(tableName: string, queryFn: Function): Observable<any[]>
324
+
325
+ Execute custom queries:
326
+
327
+ ```typescript
328
+ this.dbManager.queryTableRecords('users', (table) => {
329
+ return table
330
+ .where('age')
331
+ .above(25)
332
+ .sortBy('name');
333
+ }).subscribe(users => {
334
+ console.log('Users over 25, sorted by name:', users);
335
+ });
336
+ ```
337
+
338
+ #### countTableRecords(tableName: string): Observable<number>
339
+
340
+ Count records in a table:
341
+
342
+ ```typescript
343
+ this.dbManager.countTableRecords('users').subscribe(count => {
344
+ console.log('Total users:', count);
345
+ });
346
+ ```
347
+
348
+ ### Bulk Operations
349
+
350
+ #### bulkCreateTableRecords(tableName: string, dataArray: any[]): Observable<any[]>
351
+
352
+ Optimized bulk insert:
353
+
354
+ ```typescript
355
+ const largeDataset = Array.from({length: 1000}, (_, i) => ({
356
+ name: `User ${i}`,
357
+ email: `user${i}@example.com`,
358
+ age: Math.floor(Math.random() * 50) + 18
359
+ }));
360
+
361
+ this.dbManager.bulkCreateTableRecords('users', largeDataset).subscribe(result => {
362
+ console.log('Bulk insert completed:', result.length, 'records');
363
+ });
364
+ ```
365
+
366
+ #### bulkDeleteTableRecords(tableName: string, ids: any[]): Observable<void>
367
+
368
+ Bulk delete by IDs:
369
+
370
+ ```typescript
371
+ const idsToDelete = [1, 2, 3, 4, 5];
372
+
373
+ this.dbManager.bulkDeleteTableRecords('users', idsToDelete).subscribe(() => {
374
+ console.log('Bulk delete completed');
375
+ });
376
+ ```
377
+
378
+ ### Table Maintenance
379
+
380
+ #### clearTable(table: string): Observable<any>
381
+
382
+ Clear all records from a table:
383
+
384
+ ```typescript
385
+ this.dbManager.clearTable('users').subscribe(() => {
386
+ console.log('All user records cleared');
387
+ });
388
+ ```
389
+
390
+ #### deleteDatabaseTable(tableName: string): Observable<void>
391
+
392
+ Delete an entire table:
393
+
394
+ ```typescript
395
+ this.dbManager.deleteDatabaseTable('old_table').subscribe(() => {
396
+ console.log('Table deleted');
397
+ });
398
+ ```
399
+
400
+ ## Configuration
401
+
402
+ ### Table Schema Definition
403
+
404
+ ```typescript
405
+ interface TableSchemaDef {
406
+ table: string; // Table name
407
+ schema: string; // Dexie schema syntax
408
+ }
409
+
410
+ // Common schema patterns
411
+ const schemas = {
412
+ // Simple table with auto-increment ID
413
+ simple: '++id, name, email',
414
+
415
+ // Table with custom primary key
416
+ customKey: 'id, name, email',
417
+
418
+ // Table with indexes
419
+ indexed: '++id, name, email, age',
420
+
421
+ // Table with compound indexes
422
+ compound: '++id, [firstName+lastName], email, age',
423
+
424
+ // Table with dates and complex types
425
+ complex: '++id, name, email, createdAt, metadata'
426
+ };
427
+
428
+ // Create schema definition
429
+ const tableDef = TableSchemaDef.adapt({
430
+ table: 'users',
431
+ schema: '++id, name, email, age, createdAt'
432
+ });
433
+ ```
434
+
435
+ ### Schema Syntax Reference
436
+
437
+ | Syntax | Description | Example |
438
+ |--------|-------------|---------|
439
+ | `++id` | Auto-increment primary key | `++id` |
440
+ | `id` | String/increment primary key | `id` |
441
+ | `name` | Indexed field | `name` |
442
+ | `[field1+field2]` | Compound index | `[firstName+lastName]` |
443
+ | `*tags` | Multi-entry index | `*tags` |
444
+
445
+ ## Advanced Examples
446
+
447
+ ### E-commerce Product Catalog
448
+
449
+ ```typescript
450
+ @Injectable()
451
+ export class ProductCatalogService {
452
+ private dbManager = inject(DatabaseManagerService);
453
+
454
+ constructor() {
455
+ this.initializeProductTables();
456
+ }
457
+
458
+ private initializeProductTables() {
459
+ // Products table
460
+ const productSchema = TableSchemaDef.adapt({
461
+ table: 'products',
462
+ schema: '++id, name, description, price, categoryId, brand, tags, createdAt, updatedAt'
463
+ });
464
+
465
+ // Categories table
466
+ const categorySchema = TableSchemaDef.adapt({
467
+ table: 'categories',
468
+ schema: '++id, name, description, parentId'
469
+ });
470
+
471
+ // Reviews table
472
+ const reviewSchema = TableSchemaDef.adapt({
473
+ table: 'reviews',
474
+ schema: '++id, productId, userId, rating, comment, createdAt'
475
+ });
476
+
477
+ // Initialize all tables
478
+ [productSchema, categorySchema, reviewSchema].forEach(schema => {
479
+ this.dbManager.createDatabaseTable(schema).subscribe({
480
+ next: () => console.log(`Table ${schema.table} initialized`),
481
+ error: (error) => console.error(`Failed to create ${schema.table}:`, error)
482
+ });
483
+ });
484
+ }
485
+
486
+ // Product operations
487
+ addProduct(product: any) {
488
+ return this.dbManager.createTableRecord('products', {
489
+ ...product,
490
+ createdAt: new Date(),
491
+ updatedAt: new Date()
492
+ });
493
+ }
494
+
495
+ getProduct(id: number) {
496
+ return this.dbManager.getTableRecord('products', id);
497
+ }
498
+
499
+ getAllProducts() {
500
+ return this.dbManager.getTableRecords('products');
501
+ }
502
+
503
+ updateProduct(product: any) {
504
+ return this.dbManager.updateTableRecord('products', {
505
+ ...product,
506
+ updatedAt: new Date()
507
+ });
508
+ }
509
+
510
+ deleteProduct(id: number) {
511
+ // Delete product and its reviews
512
+ return this.dbManager.deleteTableRecord('products', id).pipe(
513
+ switchMap(() => this.dbManager.queryTableRecords('reviews', (table) =>
514
+ table.where('productId').equals(id).delete()
515
+ ))
516
+ );
517
+ }
518
+
519
+ // Search and filtering
520
+ searchProducts(query: string) {
521
+ return this.dbManager.queryTableRecords('products', (table) => {
522
+ return table
523
+ .filter(product =>
524
+ product.name.toLowerCase().includes(query.toLowerCase()) ||
525
+ product.description.toLowerCase().includes(query.toLowerCase())
526
+ )
527
+ .sortBy('name');
528
+ });
529
+ }
530
+
531
+ getProductsByCategory(categoryId: number) {
532
+ return this.dbManager.findTableRecords('products', 'categoryId', categoryId);
533
+ }
534
+
535
+ getProductsByPriceRange(minPrice: number, maxPrice: number) {
536
+ return this.dbManager.queryTableRecords('products', (table) => {
537
+ return table
538
+ .where('price')
539
+ .between(minPrice, maxPrice)
540
+ .sortBy('price');
541
+ });
542
+ }
543
+
544
+ getPopularProducts(limit: number = 10) {
545
+ return this.dbManager.queryTableRecords('reviews', (table) => {
546
+ return table
547
+ .toArray()
548
+ .then(reviews => {
549
+ // Calculate average ratings
550
+ const productRatings = new Map();
551
+ reviews.forEach(review => {
552
+ const current = productRatings.get(review.productId) || { total: 0, count: 0 };
553
+ productRatings.set(review.productId, {
554
+ total: current.total + review.rating,
555
+ count: current.count + 1
556
+ });
557
+ });
558
+
559
+ // Get top rated products
560
+ const topRated = Array.from(productRatings.entries())
561
+ .map(([productId, rating]) => ({
562
+ productId,
563
+ averageRating: rating.total / rating.count,
564
+ reviewCount: rating.count
565
+ }))
566
+ .sort((a, b) => b.averageRating - a.averageRating)
567
+ .slice(0, limit);
568
+
569
+ return topRated;
570
+ });
571
+ });
572
+ }
573
+ }
574
+ ```
575
+
576
+ ### Offline-First User Profile Management
577
+
578
+ ```typescript
579
+ @Injectable()
580
+ export class UserProfileService {
581
+ private dbManager = inject(DatabaseManagerService);
582
+ private syncQueue: any[] = [];
583
+
584
+ constructor() {
585
+ this.initializeUserTables();
586
+ this.setupOnlineSync();
587
+ }
588
+
589
+ private initializeUserTables() {
590
+ const userSchema = TableSchemaDef.adapt({
591
+ table: 'user_profiles',
592
+ schema: '++id, userId, email, profileData, lastSyncAt, isDirty'
593
+ });
594
+
595
+ const activitySchema = TableSchemaDef.adapt({
596
+ table: 'user_activities',
597
+ schema: '++id, userId, activityType, data, timestamp'
598
+ });
599
+
600
+ [userSchema, activitySchema].forEach(schema => {
601
+ this.dbManager.createDatabaseTable(schema).subscribe({
602
+ next: () => console.log(`Table ${schema.table} initialized`),
603
+ error: (error) => console.error(`Failed to create ${schema.table}:`, error)
604
+ });
605
+ });
606
+ }
607
+
608
+ // Profile management
609
+ saveProfile(userId: string, profileData: any) {
610
+ const profile = {
611
+ userId,
612
+ email: profileData.email,
613
+ profileData,
614
+ lastSyncAt: new Date(),
615
+ isDirty: !navigator.onLine // Mark as dirty if offline
616
+ };
617
+
618
+ return this.dbManager.createTableRecord('user_profiles', profile).pipe(
619
+ tap(() => {
620
+ if (!navigator.onLine) {
621
+ this.syncQueue.push({ action: 'create', data: profile });
622
+ this.saveSyncQueue();
623
+ }
624
+ })
625
+ );
626
+ }
627
+
628
+ getProfile(userId: string) {
629
+ return this.dbManager.findTableRecords('user_profiles', 'userId', userId).pipe(
630
+ map(profiles => profiles[0] || null)
631
+ );
632
+ }
633
+
634
+ updateProfile(userId: string, updates: any) {
635
+ return this.getProfile(userId).pipe(
636
+ switchMap(profile => {
637
+ if (!profile) {
638
+ throw new Error('Profile not found');
639
+ }
640
+
641
+ const updatedProfile = {
642
+ ...profile,
643
+ ...updates,
644
+ lastSyncAt: new Date(),
645
+ isDirty: !navigator.onLine
646
+ };
647
+
648
+ return this.dbManager.updateTableRecord('user_profiles', updatedProfile).pipe(
649
+ tap(() => {
650
+ if (!navigator.onLine) {
651
+ this.syncQueue.push({ action: 'update', data: updatedProfile });
652
+ this.saveSyncQueue();
653
+ }
654
+ })
655
+ );
656
+ })
657
+ );
658
+ }
659
+
660
+ // Activity tracking
661
+ logActivity(userId: string, activityType: string, data: any) {
662
+ const activity = {
663
+ userId,
664
+ activityType,
665
+ data,
666
+ timestamp: new Date()
667
+ };
668
+
669
+ return this.dbManager.createTableRecord('user_activities', activity);
670
+ }
671
+
672
+ getUserActivities(userId: string, limit: number = 50) {
673
+ return this.dbManager.queryTableRecords('user_activities', (table) => {
674
+ return table
675
+ .where('userId')
676
+ .equals(userId)
677
+ .reverse()
678
+ .limit(limit)
679
+ .toArray();
680
+ });
681
+ }
682
+
683
+ // Sync management
684
+ private setupOnlineSync() {
685
+ window.addEventListener('online', () => {
686
+ console.log('Back online, syncing data...');
687
+ this.syncPendingChanges();
688
+ });
689
+ }
690
+
691
+ private syncPendingChanges() {
692
+ const queue = this.loadSyncQueue();
693
+
694
+ queue.forEach(item => {
695
+ switch (item.action) {
696
+ case 'create':
697
+ this.syncCreate(item.data);
698
+ break;
699
+ case 'update':
700
+ this.syncUpdate(item.data);
701
+ break;
702
+ case 'delete':
703
+ this.syncDelete(item.data);
704
+ break;
705
+ }
706
+ });
707
+
708
+ // Clear queue after successful sync
709
+ this.syncQueue = [];
710
+ this.saveSyncQueue();
711
+ }
712
+
713
+ private syncCreate(data: any) {
714
+ // Sync with server API
715
+ console.log('Syncing create operation:', data);
716
+ // Implementation would depend on your API
717
+ }
718
+
719
+ private syncUpdate(data: any) {
720
+ // Sync with server API
721
+ console.log('Syncing update operation:', data);
722
+ // Implementation would depend on your API
723
+ }
724
+
725
+ private syncDelete(data: any) {
726
+ // Sync with server API
727
+ console.log('Syncing delete operation:', data);
728
+ // Implementation would depend on your API
729
+ }
730
+
731
+ private saveSyncQueue() {
732
+ localStorage.setItem('sync_queue', JSON.stringify(this.syncQueue));
733
+ }
734
+
735
+ private loadSyncQueue(): any[] {
736
+ try {
737
+ const queue = localStorage.getItem('sync_queue');
738
+ return queue ? JSON.parse(queue) : [];
739
+ } catch (error) {
740
+ console.error('Failed to load sync queue:', error);
741
+ return [];
742
+ }
743
+ }
744
+
745
+ // Data export/import for backup
746
+ exportUserData(userId: string) {
747
+ return combineLatest([
748
+ this.getProfile(userId),
749
+ this.getUserActivities(userId, 1000) // Export more activities
750
+ ]).pipe(
751
+ map(([profile, activities]) => ({
752
+ profile,
753
+ activities,
754
+ exportedAt: new Date().toISOString()
755
+ }))
756
+ );
757
+ }
758
+
759
+ importUserData(userId: string, data: any) {
760
+ return this.dbManager.createTableRecords('user_profiles', [data.profile]).pipe(
761
+ switchMap(() =>
762
+ this.dbManager.createTableRecords('user_activities', data.activities)
763
+ )
764
+ );
765
+ }
766
+ }
767
+ ```
768
+
769
+ ### Real-time Analytics Data Store
770
+
771
+ ```typescript
772
+ @Injectable()
773
+ export class AnalyticsDataService {
774
+ private dbManager = inject(DatabaseManagerService);
775
+ private readonly MAX_RECORDS = 10000;
776
+
777
+ constructor() {
778
+ this.initializeAnalyticsTables();
779
+ }
780
+
781
+ private initializeAnalyticsTables() {
782
+ const eventsSchema = TableSchemaDef.adapt({
783
+ table: 'analytics_events',
784
+ schema: '++id, eventType, userId, sessionId, timestamp, data'
785
+ });
786
+
787
+ const sessionsSchema = TableSchemaDef.adapt({
788
+ table: 'analytics_sessions',
789
+ schema: '++id, sessionId, userId, startTime, endTime, duration, pageViews'
790
+ });
791
+
792
+ const metricsSchema = TableSchemaDef.adapt({
793
+ table: 'analytics_metrics',
794
+ schema: '++id, metricName, value, timestamp, dimensions'
795
+ });
796
+
797
+ [eventsSchema, sessionsSchema, metricsSchema].forEach(schema => {
798
+ this.dbManager.createDatabaseTable(schema).subscribe({
799
+ next: () => console.log(`Analytics table ${schema.table} initialized`),
800
+ error: (error) => console.error(`Failed to create analytics table:`, error)
801
+ });
802
+ });
803
+ }
804
+
805
+ // Event tracking
806
+ trackEvent(eventType: string, userId: string, sessionId: string, data: any) {
807
+ const event = {
808
+ eventType,
809
+ userId,
810
+ sessionId,
811
+ timestamp: new Date(),
812
+ data
813
+ };
814
+
815
+ return this.dbManager.createTableRecord('analytics_events', event).pipe(
816
+ tap(() => this.cleanupOldEvents())
817
+ );
818
+ }
819
+
820
+ // Session management
821
+ startSession(userId: string, sessionId: string) {
822
+ const session = {
823
+ sessionId,
824
+ userId,
825
+ startTime: new Date(),
826
+ endTime: null,
827
+ duration: 0,
828
+ pageViews: 0
829
+ };
830
+
831
+ return this.dbManager.createTableRecord('analytics_sessions', session);
832
+ }
833
+
834
+ endSession(sessionId: string) {
835
+ return this.dbManager.queryTableRecords('analytics_sessions', (table) => {
836
+ return table.where('sessionId').equals(sessionId).first();
837
+ }).pipe(
838
+ switchMap(session => {
839
+ if (!session) {
840
+ throw new Error('Session not found');
841
+ }
842
+
843
+ const endTime = new Date();
844
+ const duration = endTime.getTime() - session.startTime.getTime();
845
+
846
+ const updatedSession = {
847
+ ...session,
848
+ endTime,
849
+ duration
850
+ };
851
+
852
+ return this.dbManager.updateTableRecord('analytics_sessions', updatedSession);
853
+ })
854
+ );
855
+ }
856
+
857
+ // Metrics calculation
858
+ recordMetric(metricName: string, value: number, dimensions: any = {}) {
859
+ const metric = {
860
+ metricName,
861
+ value,
862
+ timestamp: new Date(),
863
+ dimensions
864
+ };
865
+
866
+ return this.dbManager.createTableRecord('analytics_metrics', metric);
867
+ }
868
+
869
+ getDailyMetrics(metricName: string, date: Date) {
870
+ const startOfDay = new Date(date.getFullYear(), date.getMonth(), date.getDate());
871
+ const endOfDay = new Date(startOfDay.getTime() + 24 * 60 * 60 * 1000);
872
+
873
+ return this.dbManager.queryTableRecords('analytics_metrics', (table) => {
874
+ return table
875
+ .where('metricName')
876
+ .equals(metricName)
877
+ .and(metric =>
878
+ metric.timestamp >= startOfDay && metric.timestamp < endOfDay
879
+ )
880
+ .toArray();
881
+ });
882
+ }
883
+
884
+ getUserBehaviorReport(userId: string, days: number = 7) {
885
+ const startDate = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
886
+
887
+ return this.dbManager.queryTableRecords('analytics_events', (table) => {
888
+ return table
889
+ .where('userId')
890
+ .equals(userId)
891
+ .and(event => event.timestamp >= startDate)
892
+ .sortBy('timestamp');
893
+ }).pipe(
894
+ map(events => {
895
+ // Process events into meaningful metrics
896
+ const eventCounts = events.reduce((acc, event) => {
897
+ acc[event.eventType] = (acc[event.eventType] || 0) + 1;
898
+ return acc;
899
+ }, {});
900
+
901
+ const sessionData = events.reduce((acc, event) => {
902
+ const sessionId = event.sessionId;
903
+ if (!acc[sessionId]) {
904
+ acc[sessionId] = {
905
+ sessionId,
906
+ eventCount: 0,
907
+ startTime: event.timestamp,
908
+ endTime: event.timestamp,
909
+ duration: 0
910
+ };
911
+ }
912
+
913
+ acc[sessionId].eventCount++;
914
+ acc[sessionId].endTime = event.timestamp;
915
+ acc[sessionId].duration = acc[sessionId].endTime - acc[sessionId].startTime;
916
+
917
+ return acc;
918
+ }, {});
919
+
920
+ return {
921
+ userId,
922
+ period: { startDate, endDate: new Date() },
923
+ totalEvents: events.length,
924
+ eventTypes: eventCounts,
925
+ sessions: Object.values(sessionData),
926
+ averageSessionDuration: Object.values(sessionData).reduce((sum: number, session: any) =>
927
+ sum + session.duration, 0) / Object.keys(sessionData).length
928
+ };
929
+ })
930
+ );
931
+ }
932
+
933
+ // Data cleanup
934
+ private cleanupOldEvents() {
935
+ this.dbManager.countTableRecords('analytics_events').subscribe(count => {
936
+ if (count > this.MAX_RECORDS) {
937
+ const recordsToDelete = count - this.MAX_RECORDS;
938
+
939
+ this.dbManager.queryTableRecords('analytics_events', (table) => {
940
+ return table
941
+ .orderBy('timestamp')
942
+ .limit(recordsToDelete)
943
+ .toArray()
944
+ .then(events => {
945
+ const ids = events.map(event => event.id);
946
+ return this.dbManager.bulkDeleteTableRecords('analytics_events', ids);
947
+ });
948
+ }).subscribe();
949
+ }
950
+ });
951
+ }
952
+
953
+ // Aggregated data for dashboard
954
+ getDashboardMetrics() {
955
+ const today = new Date();
956
+ const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);
957
+ const weekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
958
+
959
+ return combineLatest([
960
+ this.getDailyMetrics('page_views', today),
961
+ this.getDailyMetrics('page_views', yesterday),
962
+ this.dbManager.queryTableRecords('analytics_sessions', (table) =>
963
+ table.where('startTime').above(weekAgo).toArray()
964
+ )
965
+ ]).pipe(
966
+ map(([todayViews, yesterdayViews, weeklySessions]) => ({
967
+ todayViews: todayViews.length,
968
+ yesterdayViews: yesterdayViews.length,
969
+ weeklyActiveUsers: new Set(weeklySessions.map(s => s.userId)).size,
970
+ weeklySessions: weeklySessions.length,
971
+ averageSessionDuration: weeklySessions.reduce((sum, s) => sum + s.duration, 0) / weeklySessions.length
972
+ }))
973
+ );
974
+ }
975
+ }
976
+ ```
977
+
978
+ ## Performance Optimization
979
+
980
+ ### Indexing Strategy
981
+
982
+ ```typescript
983
+ // ✅ Good - Proper indexing
984
+ const wellIndexedSchema = TableSchemaDef.adapt({
985
+ table: 'products',
986
+ schema: `
987
+ ++id,
988
+ name,
989
+ price,
990
+ categoryId,
991
+ [categoryId+brand],
992
+ *tags,
993
+ createdAt
994
+ `
995
+ });
996
+
997
+ // ❌ Avoid - No indexes on frequently queried fields
998
+ const poorSchema = TableSchemaDef.adapt({
999
+ table: 'products',
1000
+ schema: '++id, name, price, categoryId, description'
1001
+ });
1002
+ ```
1003
+
1004
+ ### Batch Operations
1005
+
1006
+ ```typescript
1007
+ @Injectable()
1008
+ export class OptimizedDataService {
1009
+ private dbManager = inject(DatabaseManagerService);
1010
+
1011
+ // Batch insert for better performance
1012
+ bulkInsertUsers(users: any[]) {
1013
+ // Process in chunks to avoid memory issues
1014
+ const chunkSize = 100;
1015
+ const chunks = this.chunkArray(users, chunkSize);
1016
+
1017
+ return from(chunks).pipe(
1018
+ mergeMap(chunk =>
1019
+ this.dbManager.bulkCreateTableRecords('users', chunk),
1020
+ 2 // Process 2 chunks concurrently
1021
+ )
1022
+ );
1023
+ }
1024
+
1025
+ // Efficient searching
1026
+ searchUsersAdvanced(query: string, filters: any) {
1027
+ return this.dbManager.queryTableRecords('users', (table) => {
1028
+ let result = table.toCollection();
1029
+
1030
+ // Apply filters efficiently using indexes
1031
+ if (filters.ageMin !== undefined) {
1032
+ result = result.and(user => user.age >= filters.ageMin);
1033
+ }
1034
+
1035
+ if (filters.ageMax !== undefined) {
1036
+ result = result.and(user => user.age <= filters.ageMax);
1037
+ }
1038
+
1039
+ if (query) {
1040
+ result = result.and(user =>
1041
+ user.name.toLowerCase().includes(query.toLowerCase()) ||
1042
+ user.email.toLowerCase().includes(query.toLowerCase())
1043
+ );
1044
+ }
1045
+
1046
+ return result.sortBy('name');
1047
+ });
1048
+ }
1049
+
1050
+ private chunkArray(array: any[], size: number): any[][] {
1051
+ const chunks = [];
1052
+ for (let i = 0; i < array.length; i += size) {
1053
+ chunks.push(array.slice(i, i + size));
1054
+ }
1055
+ return chunks;
1056
+ }
1057
+ }
1058
+ ```
1059
+
1060
+ ## Best Practices
1061
+
1062
+ ### 1. Schema Design
1063
+
1064
+ ```typescript
1065
+ // ✅ Good - Well-designed schema
1066
+ const goodSchema = TableSchemaDef.adapt({
1067
+ table: 'ecommerce_products',
1068
+ schema: `
1069
+ ++id, // Auto-increment ID
1070
+ name, // Searchable field
1071
+ price, // Filterable field
1072
+ categoryId, // Foreign key
1073
+ [categoryId+brand], // Compound index for common queries
1074
+ *tags, // Multi-entry for filtering
1075
+ createdAt, // Timestamp for sorting
1076
+ updatedAt // Change tracking
1077
+ `
1078
+ });
1079
+
1080
+ // ❌ Avoid - Poor schema design
1081
+ const badSchema = TableSchemaDef.adapt({
1082
+ table: 'products',
1083
+ schema: '++id, name, price, description, category, brand, tags, created, updated'
1084
+ });
1085
+ ```
1086
+
1087
+ ### 2. Error Handling
1088
+
1089
+ ```typescript
1090
+ // ✅ Good - Comprehensive error handling
1091
+ addUser(user: any) {
1092
+ return this.dbManager.createTableRecord('users', user).pipe(
1093
+ catchError(error => {
1094
+ if (error.name === 'ConstraintError') {
1095
+ return throwError(() => new Error('User already exists'));
1096
+ }
1097
+ return throwError(() => new Error('Database operation failed'));
1098
+ })
1099
+ );
1100
+ }
1101
+ ```
1102
+
1103
+ ### 3. Memory Management
1104
+
1105
+ ```typescript
1106
+ // ✅ Good - Limit query results
1107
+ getRecentUsers(limit: number = 50) {
1108
+ return this.dbManager.queryTableRecords('users', (table) => {
1109
+ return table
1110
+ .orderBy('createdAt')
1111
+ .reverse()
1112
+ .limit(limit)
1113
+ .toArray();
1114
+ });
1115
+ }
1116
+ ```
1117
+
1118
+ ## Troubleshooting
1119
+
1120
+ ### Common Issues
1121
+
1122
+ #### 1. Schema Conflicts
1123
+ ```typescript
1124
+ // Check existing schema
1125
+ this.dbManager.getTableSchema('users').subscribe(schema => {
1126
+ console.log('Existing schema:', schema);
1127
+ });
1128
+
1129
+ // Handle schema updates carefully
1130
+ // Version your database schema
1131
+ const currentVersion = 1;
1132
+ const newVersion = 2;
1133
+
1134
+ // Implement migration logic
1135
+ if (currentVersion < newVersion) {
1136
+ this.migrateDatabase();
1137
+ }
1138
+ ```
1139
+
1140
+ #### 2. Large Dataset Performance
1141
+ ```typescript
1142
+ // Use pagination for large datasets
1143
+ getPaginatedUsers(page: number, pageSize: number) {
1144
+ const offset = (page - 1) * pageSize;
1145
+
1146
+ return this.dbManager.queryTableRecords('users', (table) => {
1147
+ return table
1148
+ .offset(offset)
1149
+ .limit(pageSize)
1150
+ .toArray();
1151
+ });
1152
+ }
1153
+ ```
1154
+
1155
+ #### 3. Storage Quota
1156
+ ```typescript
1157
+ // Monitor storage usage
1158
+ @Injectable()
1159
+ export class StorageMonitorService {
1160
+ private dbManager = inject(DatabaseManagerService);
1161
+
1162
+ checkStorageUsage() {
1163
+ if ('storage' in navigator && 'estimate' in navigator.storage) {
1164
+ navigator.storage.estimate().then(estimate => {
1165
+ const used = estimate.usage || 0;
1166
+ const quota = estimate.quota || 0;
1167
+ const percentage = (used / quota) * 100;
1168
+
1169
+ console.log(`Storage used: ${used} / ${quota} (${percentage.toFixed(2)}%)`);
1170
+
1171
+ if (percentage > 80) {
1172
+ this.cleanupOldData();
1173
+ }
1174
+ });
1175
+ }
1176
+ }
1177
+
1178
+ private cleanupOldData() {
1179
+ // Implement cleanup logic
1180
+ const cutoffDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000); // 30 days ago
1181
+
1182
+ this.dbManager.queryTableRecords('analytics_events', (table) => {
1183
+ return table.where('timestamp').below(cutoffDate).delete();
1184
+ }).subscribe();
1185
+ }
1186
+ }
1187
+ ```
1188
+
1189
+ ## Related Documentation
1190
+
1191
+ - [HTTP State Service](http-state/README.md)
1192
+ - [Local Storage Service](local-storage/README.md)
1193
+ - [Utils Service](utils/README.md)
1194
+ - [Architecture Overview](../architecture/README.md)
1195
+ - [Dexie.js Documentation](https://dexie.org/docs/)