http-request-manager 18.7.21 → 18.7.27

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 (198) hide show
  1. package/fesm2022/http-request-manager.mjs +7633 -0
  2. package/fesm2022/http-request-manager.mjs.map +1 -0
  3. package/http-request-manager-18.7.27.tgz +0 -0
  4. package/package.json +16 -5
  5. package/types/http-request-manager.d.ts +2277 -0
  6. package/ARCHITECTURE.md +0 -483
  7. package/DATABASE_README.md +0 -1176
  8. package/HTTP_MANAGER_README.md +0 -579
  9. package/HTTP_SINGNALS_MANAGER_README.md +0 -654
  10. package/HTTP_STATE_MANAGER_README.md +0 -948
  11. package/INTERCEPTOR_README.md +0 -549
  12. package/LOCAL_STORAGE_README.md +0 -1056
  13. package/STORE_STATE_MANAGER_README.md +0 -1322
  14. package/UTILS_README.md +0 -1186
  15. package/WS_MANAGER_README.md +0 -613
  16. package/ng-package.json +0 -8
  17. package/src/lib/http-request-manager.module.ts +0 -132
  18. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.html +0 -65
  19. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.scss +0 -0
  20. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.ts +0 -224
  21. package/src/lib/http-request-services-demo/http-request-services-demo.component.html +0 -114
  22. package/src/lib/http-request-services-demo/http-request-services-demo.component.scss +0 -6
  23. package/src/lib/http-request-services-demo/http-request-services-demo.component.ts +0 -52
  24. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.html +0 -195
  25. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.scss +0 -17
  26. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.ts +0 -206
  27. package/src/lib/http-request-services-demo/local-storage-signals-demo/local-storage-signals-demo.component.html +0 -200
  28. package/src/lib/http-request-services-demo/local-storage-signals-demo/local-storage-signals-demo.component.scss +0 -17
  29. package/src/lib/http-request-services-demo/local-storage-signals-demo/local-storage-signals-demo.component.ts +0 -212
  30. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.html +0 -53
  31. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.scss +0 -60
  32. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.ts +0 -72
  33. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-download.module.ts +0 -28
  34. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.html +0 -10
  35. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.scss +0 -29
  36. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.ts +0 -100
  37. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/models/download-labels-model.ts +0 -22
  38. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.html +0 -8
  39. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.scss +0 -19
  40. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.ts +0 -26
  41. package/src/lib/http-request-services-demo/request-manager-demo/models/app-session.model.ts +0 -30
  42. package/src/lib/http-request-services-demo/request-manager-demo/models/app.model.ts +0 -19
  43. package/src/lib/http-request-services-demo/request-manager-demo/models/get-sample.model.ts +0 -25
  44. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-ai-prompt.ts +0 -19
  45. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client-details.ts +0 -24
  46. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client-info.ts +0 -30
  47. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client.model.ts +0 -49
  48. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-mapper-client-info.ts +0 -33
  49. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.html +0 -392
  50. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.scss +0 -24
  51. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.ts +0 -461
  52. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.html +0 -393
  53. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.scss +0 -24
  54. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.ts +0 -421
  55. package/src/lib/http-request-services-demo/request-manager-state-demo/services/state-manager-demo.service.ts +0 -87
  56. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/services/state-data-request.service.ts +0 -120
  57. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-ai-messaging/ws-ai-messaging.component.css +0 -0
  58. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-ai-messaging/ws-ai-messaging.component.html +0 -3
  59. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-ai-messaging/ws-ai-messaging.component.ts +0 -16
  60. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-chats/ws-chats.component.css +0 -0
  61. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-chats/ws-chats.component.html +0 -3
  62. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-chats/ws-chats.component.ts +0 -16
  63. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.css +0 -31
  64. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.html +0 -72
  65. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.scss +0 -41
  66. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.spec.ts +0 -205
  67. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.ts +0 -77
  68. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.css +0 -11
  69. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.html +0 -96
  70. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.spec.ts +0 -31
  71. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.ts +0 -229
  72. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.css +0 -30
  73. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.html +0 -172
  74. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.spec.ts +0 -31
  75. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.ts +0 -239
  76. package/src/lib/http-request-services-demo/request-manager-ws-demo/models/oidc-client.model.ts +0 -31
  77. package/src/lib/http-request-services-demo/request-manager-ws-demo/models/user-data.model.ts +0 -32
  78. package/src/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.css +0 -0
  79. package/src/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.html +0 -84
  80. package/src/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.ts +0 -41
  81. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/index.ts +0 -3
  82. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/message-service-demo.service.ts +0 -83
  83. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/notification-service-demo.service.ts +0 -147
  84. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/state-service-demo.service.ts +0 -158
  85. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/download-file/download-file.component.html +0 -53
  86. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/download-file/download-file.component.scss +0 -60
  87. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/download-file/download-file.component.ts +0 -72
  88. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-download.module.ts +0 -28
  89. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-downloader.component.html +0 -10
  90. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-downloader.component.scss +0 -29
  91. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-downloader.component.ts +0 -100
  92. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/models/download-labels-model.ts +0 -22
  93. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/spinner/spinner.component.html +0 -8
  94. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/spinner/spinner.component.scss +0 -19
  95. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/spinner/spinner.component.ts +0 -26
  96. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/app-session.model.ts +0 -30
  97. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/app.model.ts +0 -19
  98. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/get-sample.model.ts +0 -25
  99. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-ai-prompt.ts +0 -19
  100. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-client-details.ts +0 -24
  101. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-client-info.ts +0 -30
  102. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-client.model.ts +0 -49
  103. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-mapper-client-info.ts +0 -33
  104. package/src/lib/http-request-services-demo/request-signals-manager-demo/request-signals-manager-demo.component.html +0 -380
  105. package/src/lib/http-request-services-demo/request-signals-manager-demo/request-signals-manager-demo.component.scss +0 -24
  106. package/src/lib/http-request-services-demo/request-signals-manager-demo/request-signals-manager-demo.component.ts +0 -410
  107. package/src/lib/http-request-services-demo/store-state-manager-demo/models/settings.model.ts +0 -28
  108. package/src/lib/http-request-services-demo/store-state-manager-demo/services/settings-state.service.ts +0 -48
  109. package/src/lib/http-request-services-demo/store-state-manager-demo/store-state-manager-demo.component.css +0 -0
  110. package/src/lib/http-request-services-demo/store-state-manager-demo/store-state-manager-demo.component.html +0 -23
  111. package/src/lib/http-request-services-demo/store-state-manager-demo/store-state-manager-demo.component.ts +0 -36
  112. package/src/lib/index.ts +0 -3
  113. package/src/lib/interceptors/credentials.interceptor.ts +0 -16
  114. package/src/lib/interceptors/index.ts +0 -6
  115. package/src/lib/interceptors/models/error-settings.model.ts +0 -22
  116. package/src/lib/interceptors/models/index.ts +0 -2
  117. package/src/lib/interceptors/proxy-debugger.interceptor.ts +0 -46
  118. package/src/lib/interceptors/request-error.interceptor.ts +0 -65
  119. package/src/lib/interceptors/request-header.interceptor.ts +0 -53
  120. package/src/lib/models/config-http-options.model.ts +0 -42
  121. package/src/lib/models/config-local-storage-options.model.ts +0 -27
  122. package/src/lib/models/config-options.model.ts +0 -27
  123. package/src/lib/models/config-token.model.ts +0 -9
  124. package/src/lib/models/data-type.enum.ts +0 -5
  125. package/src/lib/models/database-storage.model.ts +0 -24
  126. package/src/lib/models/index.ts +0 -12
  127. package/src/lib/models/retry-options.model.ts +0 -22
  128. package/src/lib/services/database-manager-service/database.manager.service.ts +0 -262
  129. package/src/lib/services/database-manager-service/db.storage.service.ts +0 -207
  130. package/src/lib/services/database-manager-service/index.ts +0 -4
  131. package/src/lib/services/database-manager-service/models/index.ts +0 -2
  132. package/src/lib/services/database-manager-service/models/table-schema.ts +0 -33
  133. package/src/lib/services/index.ts +0 -12
  134. package/src/lib/services/local-storage-manager-service/index.ts +0 -4
  135. package/src/lib/services/local-storage-manager-service/local-storage-manager.service.spec.ts +0 -71
  136. package/src/lib/services/local-storage-manager-service/local-storage-manager.service.ts +0 -426
  137. package/src/lib/services/local-storage-manager-service/local-storage-signals-manager.service.spec.ts +0 -67
  138. package/src/lib/services/local-storage-manager-service/local-storage-signals-manager.service.ts +0 -345
  139. package/src/lib/services/local-storage-manager-service/models/global-store-options.model.ts +0 -30
  140. package/src/lib/services/local-storage-manager-service/models/index.ts +0 -6
  141. package/src/lib/services/local-storage-manager-service/models/setting-options.model.ts +0 -35
  142. package/src/lib/services/local-storage-manager-service/models/storage-data.model.ts +0 -24
  143. package/src/lib/services/local-storage-manager-service/models/storage-option.model.ts +0 -32
  144. package/src/lib/services/local-storage-manager-service/models/storage-type.enum.ts +0 -5
  145. package/src/lib/services/request-manager-services/README.md +0 -268
  146. package/src/lib/services/request-manager-services/http-manager-signals.service.ts +0 -246
  147. package/src/lib/services/request-manager-services/http-manager.service.spec.ts +0 -232
  148. package/src/lib/services/request-manager-services/http-manager.service.ts +0 -274
  149. package/src/lib/services/request-manager-services/index.ts +0 -8
  150. package/src/lib/services/request-manager-services/request-signals.service.ts +0 -214
  151. package/src/lib/services/request-manager-services/request.service.ts +0 -309
  152. package/src/lib/services/request-manager-services/rxjs-operators/countdown.ts +0 -17
  153. package/src/lib/services/request-manager-services/rxjs-operators/delay-retry.ts +0 -16
  154. package/src/lib/services/request-manager-services/rxjs-operators/index.ts +0 -4
  155. package/src/lib/services/request-manager-services/rxjs-operators/request-polling.ts +0 -35
  156. package/src/lib/services/request-manager-services/rxjs-operators/request-streaming.ts +0 -436
  157. package/src/lib/services/request-manager-state-service/http-manager-state.store.ts +0 -1321
  158. package/src/lib/services/request-manager-state-service/index.ts +0 -3
  159. package/src/lib/services/request-manager-state-service/models/api-request.model.ts +0 -61
  160. package/src/lib/services/request-manager-state-service/models/index.ts +0 -6
  161. package/src/lib/services/request-manager-state-service/models/request-options.model.ts +0 -22
  162. package/src/lib/services/request-manager-state-service/models/stream-type.enum.ts +0 -13
  163. package/src/lib/services/request-manager-state-service/models/ws-options.model.ts +0 -39
  164. package/src/lib/services/store-state-manager-service/index.ts +0 -3
  165. package/src/lib/services/store-state-manager-service/models/index.ts +0 -2
  166. package/src/lib/services/store-state-manager-service/models/state-storage-options.model.ts +0 -24
  167. package/src/lib/services/store-state-manager-service/store-state-manager.service.ts +0 -88
  168. package/src/lib/services/utils/app.service.spec.ts +0 -25
  169. package/src/lib/services/utils/app.service.ts +0 -21
  170. package/src/lib/services/utils/encryption/README.md +0 -79
  171. package/src/lib/services/utils/encryption/asymmetrical-encryption.service.ts +0 -282
  172. package/src/lib/services/utils/encryption/encryption-test.service.ts +0 -39
  173. package/src/lib/services/utils/encryption/index.ts +0 -5
  174. package/src/lib/services/utils/encryption/random.ts +0 -81
  175. package/src/lib/services/utils/encryption/symmetrical-encryption.service.ts +0 -93
  176. package/src/lib/services/utils/headers.service.spec.ts +0 -80
  177. package/src/lib/services/utils/headers.service.ts +0 -18
  178. package/src/lib/services/utils/index.ts +0 -7
  179. package/src/lib/services/utils/object-merger.service.spec.ts +0 -18
  180. package/src/lib/services/utils/object-merger.service.ts +0 -78
  181. package/src/lib/services/utils/path-query.service.spec.ts +0 -117
  182. package/src/lib/services/utils/path-query.service.ts +0 -69
  183. package/src/lib/services/utils/random-color.utils.ts +0 -83
  184. package/src/lib/services/utils/utils.service.spec.ts +0 -165
  185. package/src/lib/services/utils/utils.service.ts +0 -192
  186. package/src/lib/services/ws-manager-service/index.ts +0 -4
  187. package/src/lib/services/ws-manager-service/models/channel-info.model.ts +0 -24
  188. package/src/lib/services/ws-manager-service/models/channel-message-data.model.ts +0 -24
  189. package/src/lib/services/ws-manager-service/models/channel-message.model.ts +0 -24
  190. package/src/lib/services/ws-manager-service/models/communication-type.enum.ts +0 -5
  191. package/src/lib/services/ws-manager-service/models/index.ts +0 -5
  192. package/src/lib/services/ws-manager-service/models/ws-user.model.ts +0 -38
  193. package/src/lib/services/ws-manager-service/services/index.ts +0 -3
  194. package/src/lib/services/ws-manager-service/services/websocket.service.ts +0 -392
  195. package/src/public-api.ts +0 -14
  196. package/tsconfig.lib.json +0 -32
  197. package/tsconfig.lib.prod.json +0 -10
  198. package/tsconfig.spec.json +0 -14
@@ -1,948 +0,0 @@
1
- # HTTP Manager State Service
2
-
3
- The `HTTPManagerStateService` extends `ComponentStore` to provide robust state management with built-in HTTP request handling and WebSocket integration for CRUD operations.
4
-
5
- ## Overview
6
-
7
- This service combines HTTP requests with local state management, automatically updating the local store when CRUD operations succeed. It integrates with WebSockets to keep the state synchronized with server-side changes.
8
-
9
- ### Key Features
10
-
11
- - **ComponentStore Integration** - Extends NGRX ComponentStore for robust state management
12
- - **Automatic CRUD Updates** - `createRecord`, `updateRecord`, and `deleteRecord` automatically update local state
13
- - **WebSocket Sync** - Real-time synchronization with server via WebSocket channels
14
- - **Database Support** - IndexedDB caching integration for offline-first applications
15
- - **Selectors** - Built-in selectors like `data$` and `selectRecord$(id)` for data access
16
- - **Pagination** - State tracking for paginated data
17
- - **Streaming Support** - Real-time data streaming integration
18
-
19
- ## Installation
20
-
21
- ```typescript
22
- import { HttpRequestManagerModule } from 'http-request-manager';
23
-
24
- @NgModule({
25
- imports: [HttpRequestManagerModule.forRoot({})]
26
- })
27
- export class AppModule { }
28
- ```
29
-
30
- ## Basic Usage
31
-
32
- ### Creating a State Service
33
-
34
- ```typescript
35
- import { Injectable } from '@angular/core';
36
- import { HTTPManagerStateService, ApiRequest, DataType } from 'http-request-manager';
37
-
38
- interface User {
39
- id: number;
40
- name: string;
41
- email: string;
42
- active: boolean;
43
- }
44
-
45
- @Injectable({
46
- providedIn: 'root'
47
- })
48
- export class UserStateService extends HTTPManagerStateService<User> {
49
-
50
- constructor() {
51
- super(
52
- ApiRequest.adapt({
53
- server: 'http://localhost:8080',
54
- path: ['users'],
55
- adapter: User.adapt, // Required for Database Storage
56
- ws: {
57
- id: 'USERS123', // Base name - automatically becomes SYS-USERS123
58
- wsServer: 'ws://localhost:8080',
59
- retry: { times: 3, delay: 5 }
60
- }
61
- }),
62
- DataType.ARRAY,
63
- DatabaseStorage.adapt({
64
- table: 'users-cache',
65
- expiresIn: '1d' // Cache for 1 day
66
- })
67
- );
68
- }
69
-
70
- // Public API methods
71
- loadUsers() {
72
- this.fetchRecords();
73
- }
74
-
75
- addUser(user: Omit<User, 'id'>) {
76
- this.createRecord(user);
77
- }
78
-
79
- updateUser(user: User) {
80
- this.updateRecord(user);
81
- }
82
-
83
- deleteUser(id: number) {
84
- this.deleteRecord(id);
85
- }
86
-
87
- getUser(id: number) {
88
- return this.selectRecord$(id);
89
- }
90
- }
91
- ```
92
-
93
- ### Using in Components
94
-
95
- ```typescript
96
- import { Component, inject } from '@angular/core';
97
- import { UserStateService } from './user-state.service';
98
-
99
- @Component({
100
- selector: 'app-users',
101
- template: `
102
- <div class="user-management">
103
- <h2>User Management</h2>
104
-
105
- <!-- Loading State -->
106
- <div *ngIf="store.isPending$ | async">
107
- <div class="loading-spinner">Loading users...</div>
108
- </div>
109
-
110
- <!-- Error State -->
111
- <div *ngIf="store.error$ | async as error" class="error">
112
- Error: {{ error.message }}
113
- </div>
114
-
115
- <!-- User List -->
116
- <div class="user-grid">
117
- <div *ngFor="let user of store.data$ | async" class="user-card">
118
- <div class="user-info">
119
- <h3>{{ user.name }}</h3>
120
- <p>{{ user.email }}</p>
121
- <span class="user-status"
122
- [class.active]="user.active"
123
- [class.inactive]="!user.active">
124
- {{ user.active ? 'Active' : 'Inactive' }}
125
- </span>
126
- </div>
127
-
128
- <div class="user-actions">
129
- <button (click)="store.updateUser({...user, active: !user.active})">
130
- {{ user.active ? 'Deactivate' : 'Activate' }}
131
- </button>
132
- <button (click)="store.deleteUser(user.id)" class="delete">
133
- Delete
134
- </button>
135
- </div>
136
- </div>
137
- </div>
138
-
139
- <!-- Add User Form -->
140
- <div class="add-user-form">
141
- <h3>Add New User</h3>
142
- <form (ngSubmit)="addUser()">
143
- <input [(ngModel)]="newUser.name" name="name" placeholder="Name" required>
144
- <input [(ngModel)]="newUser.email" name="email" placeholder="Email" required>
145
- <label>
146
- <input type="checkbox" [(ngModel)]="newUser.active" name="active">
147
- Active
148
- </label>
149
- <button type="submit">Add User</button>
150
- </form>
151
- </div>
152
- </div>
153
- `
154
- })
155
- export class UsersComponent {
156
- store = inject(UserStateService);
157
-
158
- newUser = {
159
- name: '',
160
- email: '',
161
- active: true
162
- };
163
-
164
- ngOnInit() {
165
- this.store.loadUsers();
166
- }
167
-
168
- addUser() {
169
- if (this.newUser.name && this.newUser.email) {
170
- this.store.addUser(this.newUser);
171
- this.newUser = { name: '', email: '', active: true };
172
- }
173
- }
174
- }
175
- ```
176
-
177
- ## API Reference
178
-
179
- ### State Interface
180
-
181
- The service manages state with the following interface:
182
-
183
- ```typescript
184
- interface State<T> {
185
- records: T[]; // Array of entities
186
- record: T | null; // Single selected entity
187
- page: number; // Current page
188
- totalPages: number; // Total pages
189
- isPending: boolean; // Loading state
190
- error: any; // Error state
191
- }
192
- ```
193
-
194
- ### Selectors
195
-
196
- #### data$: Observable<T[]>
197
-
198
- Get all records from the state:
199
-
200
- ```typescript
201
- users$ = this.store.data$;
202
- ```
203
-
204
- #### record$: Observable<T | null>
205
-
206
- Get the currently selected record:
207
-
208
- ```typescript
209
- selectedUser$ = this.store.record$;
210
- ```
211
-
212
- #### selectRecord$(id: any): Observable<T | undefined>
213
-
214
- Get a specific record by ID:
215
-
216
- ```typescript
217
- user$ = this.store.selectRecord$(123);
218
- ```
219
-
220
- #### isPending$: Observable<boolean>
221
-
222
- Check if any operation is in progress:
223
-
224
- ```typescript
225
- loading$ = this.store.isPending$;
226
- ```
227
-
228
- #### error$: Observable<any>
229
-
230
- Get the current error state:
231
-
232
- ```typescript
233
- error$ = this.store.error$;
234
- ```
235
-
236
- #### page$: Observable<number>
237
-
238
- Get the current page number:
239
-
240
- ```typescript
241
- currentPage$ = this.store.page$;
242
- ```
243
-
244
- #### totalPages$: Observable<number>
245
-
246
- Get the total number of pages:
247
-
248
- ```typescript
249
- totalPages$ = this.store.totalPages$;
250
- ```
251
-
252
- ### CRUD Methods
253
-
254
- #### fetchRecords(params?: any)
255
-
256
- Fetch records from the API:
257
-
258
- ```typescript
259
- // Basic fetch
260
- this.store.fetchRecords();
261
-
262
- // Fetch with parameters
263
- this.store.fetchRecords({ page: 1, limit: 10, search: 'john' });
264
- ```
265
-
266
- #### createRecord(record: T)
267
-
268
- Create a new record and update state:
269
-
270
- ```typescript
271
- this.store.createRecord({
272
- name: 'John Doe',
273
- email: 'john@example.com',
274
- active: true
275
- });
276
- ```
277
-
278
- #### updateRecord(record: T)
279
-
280
- Update an existing record and update state:
281
-
282
- ```typescript
283
- this.store.updateRecord({
284
- id: 123,
285
- name: 'John Smith',
286
- email: 'john.smith@example.com',
287
- active: true
288
- });
289
- ```
290
-
291
- #### deleteRecord(id: any)
292
-
293
- Delete a record and update state:
294
-
295
- ```typescript
296
- this.store.deleteRecord(123);
297
- ```
298
-
299
- #### setPage(page: number)
300
-
301
- Set the current page:
302
-
303
- ```typescript
304
- this.store.setPage(2);
305
- ```
306
-
307
- #### setTotalPages(total: number)
308
-
309
- Set the total number of pages:
310
-
311
- ```typescript
312
- this.store.setTotalPages(10);
313
- ```
314
-
315
- ## WebSocket Integration
316
-
317
- The HTTPManagerStateService automatically handles WebSocket connections for real-time state synchronization.
318
-
319
- ### Channel Types
320
-
321
- The service uses three types of WebSocket channels:
322
-
323
- | Channel Type | Prefix | Description | Purpose |
324
- |--------------|--------|-------------|---------|
325
- | **STATE** | `SYS-` | State synchronization | CRUD operations sync |
326
- | **MESSAGE** | `MES-` | Messaging channels | Real-time messaging |
327
- | **NOTIFICATION** | `PUB-` | Notification channels | System notifications |
328
-
329
- ### Configuration
330
-
331
- ```typescript
332
- constructor() {
333
- super(
334
- ApiRequest.adapt({
335
- server: 'http://localhost:8080',
336
- path: ['users'],
337
- ws: {
338
- id: 'USERS123', // Base name becomes SYS-USERS123
339
- wsServer: 'ws://localhost:8080',
340
- jwtToken: 'your-jwt-token',
341
- retry: { times: 3, delay: 5 }
342
- }
343
- }),
344
- DataType.ARRAY
345
- );
346
- }
347
- ```
348
-
349
- ### WebSocket Observables
350
-
351
- #### connectionStatus$: Observable<boolean>
352
-
353
- Monitor WebSocket connection status:
354
-
355
- ```typescript
356
- connectionStatus$ = this.store.connectionStatus$;
357
-
358
- // Usage
359
- <div *ngIf="store.connectionStatus$ | async; disconnected" class="connection-status">
360
- Connected
361
- </div>
362
-
363
- <ng-template #disconnected>
364
- <div class="connection-status offline">
365
- Reconnecting...
366
- </div>
367
- </ng-template>
368
- ```
369
-
370
- #### communicationMessages$: Observable<any[]>
371
-
372
- Monitor incoming messages:
373
-
374
- ```typescript
375
- messages$ = this.store.communicationMessages$;
376
- ```
377
-
378
- #### notificationMessages$: Observable<any[]>
379
-
380
- Monitor notifications:
381
-
382
- ```typescript
383
- notifications$ = this.store.notificationMessages$;
384
- ```
385
-
386
- ### WebSocket Methods
387
-
388
- #### initializeConnection(wsServer: string, jwtToken: string, user: any)
389
-
390
- Initialize WebSocket connection:
391
-
392
- ```typescript
393
- this.store.initializeConnection(
394
- 'ws://localhost:8080',
395
- 'jwt-token-here',
396
- { id: 1, name: 'John Doe', email: 'john@example.com' }
397
- );
398
- ```
399
-
400
- #### setApiRequestOptions(options: ApiRequest)
401
-
402
- Update API and WebSocket configuration at runtime:
403
-
404
- ```typescript
405
- this.store.setApiRequestOptions(
406
- ApiRequest.adapt({
407
- ...this.store.apiRequestOptions,
408
- ws: {
409
- ...this.store.apiRequestOptions.ws,
410
- wsServer: 'wss://new-server.com/ws'
411
- }
412
- })
413
- );
414
- ```
415
-
416
- #### createChannel(channelName: string)
417
-
418
- Create a new messaging channel:
419
-
420
- ```typescript
421
- // Creates PUB-{channelName}
422
- this.store.createChannel('general-chat');
423
- ```
424
-
425
- #### subscribeToChannel(channelName: string)
426
-
427
- Subscribe to a messaging channel:
428
-
429
- ```typescript
430
- // Subscribes to PUB-{channelName}
431
- this.store.subscribeToChannel('general-chat');
432
- ```
433
-
434
- #### unsubscribeFromChannel(channelName: string)
435
-
436
- Unsubscribe from a channel:
437
-
438
- ```typescript
439
- this.store.unsubscribeFromChannel('general-chat');
440
- ```
441
-
442
- #### sendMessage(content: any, channels: string[])
443
-
444
- Send a message to specific channels:
445
-
446
- ```typescript
447
- this.store.sendMessage(
448
- { message: 'Hello everyone!' },
449
- ['general-chat', 'team-updates']
450
- );
451
- ```
452
-
453
- ### Real-time CRUD Operations
454
-
455
- The service automatically syncs state changes via WebSocket:
456
-
457
- ```typescript
458
- // When createRecord() is called:
459
- // 1. Makes HTTP POST request
460
- // 2. On success, updates local state
461
- // 3. Sends WebSocket message to SYS-{id} channel
462
- // 4. Other clients receive the message and update their state
463
-
464
- // When other clients call createRecord:
465
- // 1. They send WebSocket message to SYS-{id} channel
466
- // 2. This client receives the message
467
- // 3. Automatically calls fetchRecords() to get updated data
468
- ```
469
-
470
- ## Database Storage Integration
471
-
472
- For offline-first applications, configure IndexedDB caching:
473
-
474
- ```typescript
475
- @Injectable()
476
- export class UserStateService extends HTTPManagerStateService<User> {
477
-
478
- constructor() {
479
- super(
480
- ApiRequest.adapt({
481
- server: 'http://localhost:8080',
482
- path: ['users'],
483
- adapter: User.adapt // Required for Database Storage
484
- }),
485
- DataType.ARRAY,
486
- DatabaseStorage.adapt({
487
- table: 'users-cache',
488
- expiresIn: '1d' // Cache expires in 1 day
489
- })
490
- );
491
- }
492
- }
493
- ```
494
-
495
- ### Caching Behavior
496
-
497
- 1. **First Request**: Fetches from server and saves to IndexedDB
498
- 2. **Subsequent Requests**: Checks IndexedDB first, uses cached data if valid
499
- 3. **Cache Expiry**: Automatically fetches from server when cache expires
500
- 4. **Offline Mode**: Uses cached data when network is unavailable
501
-
502
- ## Advanced Examples
503
-
504
- ### Pagination State Service
505
-
506
- ```typescript
507
- @Injectable()
508
- export class PaginatedUserStateService extends HTTPManagerStateService<User> {
509
-
510
- private currentPage = signal(1);
511
- private pageSize = signal(10);
512
- private searchQuery = signal('');
513
- private sortBy = signal('name');
514
- private sortOrder = signal<'asc' | 'desc'>('asc');
515
-
516
- // Computed selectors
517
- totalPages = computed(() => Math.ceil(this.store.data$().length / this.pageSize()));
518
-
519
- paginatedData = computed(() => {
520
- const data = this.store.data$();
521
- const start = (this.currentPage() - 1) * this.pageSize();
522
- const end = start + this.pageSize();
523
- return data.slice(start, end);
524
- });
525
-
526
- constructor() {
527
- super(
528
- ApiRequest.adapt({
529
- server: 'http://localhost:8080',
530
- path: ['users'],
531
- adapter: User.adapt
532
- }),
533
- DataType.ARRAY
534
- );
535
- }
536
-
537
- loadUsers() {
538
- const params = {
539
- page: this.currentPage(),
540
- limit: this.pageSize(),
541
- search: this.searchQuery(),
542
- sortBy: this.sortBy(),
543
- sortOrder: this.sortOrder()
544
- };
545
-
546
- this.fetchRecords(params);
547
- }
548
-
549
- setPage(page: number) {
550
- this.currentPage.set(page);
551
- this.loadUsers();
552
- }
553
-
554
- setPageSize(size: number) {
555
- this.pageSize.set(size);
556
- this.currentPage.set(1); // Reset to first page
557
- this.loadUsers();
558
- }
559
-
560
- setSearchQuery(query: string) {
561
- this.searchQuery.set(query);
562
- this.currentPage.set(1); // Reset to first page
563
- this.loadUsers();
564
- }
565
-
566
- setSorting(sortBy: string, order: 'asc' | 'desc') {
567
- this.sortBy.set(sortBy);
568
- this.sortOrder.set(order);
569
- this.currentPage.set(1); // Reset to first page
570
- this.loadUsers();
571
- }
572
- }
573
- ```
574
-
575
- ### Real-time Chat with State Management
576
-
577
- ```typescript
578
- @Injectable()
579
- export class ChatStateService extends HTTPManagerStateService<ChatMessage> {
580
-
581
- private currentUser = signal<any>(null);
582
- private activeChannel = signal<string>('general');
583
-
584
- // Observables
585
- messages$ = this.store.data$;
586
- channelUsers$ = this.store.communicationMessages$;
587
- connectionStatus$ = this.store.connectionStatus$;
588
-
589
- constructor() {
590
- super(
591
- ApiRequest.adapt({
592
- server: 'http://localhost:8080',
593
- path: ['messages'],
594
- adapter: ChatMessage.adapt,
595
- ws: {
596
- id: 'CHAT_WS',
597
- wsServer: 'ws://localhost:8080'
598
- }
599
- }),
600
- DataType.ARRAY
601
- );
602
- }
603
-
604
- initializeChat(user: any) {
605
- this.currentUser.set(user);
606
- this.store.initializeConnection(
607
- 'ws://localhost:8080',
608
- user.jwtToken,
609
- user
610
- );
611
- }
612
-
613
- joinChannel(channelName: string) {
614
- this.activeChannel.set(channelName);
615
- this.store.createChannel(channelName);
616
- this.store.subscribeToChannel(channelName);
617
- }
618
-
619
- leaveChannel(channelName: string) {
620
- this.store.unsubscribeFromChannel(channelName);
621
- if (this.activeChannel() === channelName) {
622
- this.activeChannel.set('general');
623
- }
624
- }
625
-
626
- sendMessage(message: string) {
627
- const channel = this.activeChannel();
628
- const user = this.currentUser();
629
-
630
- if (!channel || !user) return;
631
-
632
- // Create message record (HTTP)
633
- this.createRecord({
634
- id: Date.now(), // Temporary ID
635
- content: message,
636
- channel: channel,
637
- userId: user.id,
638
- userName: user.name,
639
- timestamp: new Date()
640
- });
641
-
642
- // Send via WebSocket
643
- this.store.sendMessage(
644
- {
645
- message: message,
646
- userId: user.id,
647
- userName: user.name,
648
- channel: channel
649
- },
650
- [channel]
651
- );
652
- }
653
-
654
- getMessagesForChannel(channelName: string) {
655
- return this.store.data$.pipe(
656
- map(messages => messages.filter(msg => msg.channel === channelName))
657
- );
658
- }
659
- }
660
- ```
661
-
662
- ### Complex Filter and Search State
663
-
664
- ```typescript
665
- @Injectable()
666
- export class AdvancedUserStateService extends HTTPManagerStateService<User> {
667
-
668
- // Filter state
669
- activeFilter = signal<'all' | 'active' | 'inactive'>('all');
670
- roleFilter = signal<string>('');
671
- searchQuery = signal<string>('');
672
- dateRange = signal<{start: Date, end: Date} | null>(null);
673
-
674
- // Computed filters
675
- filteredUsers = computed(() => {
676
- let users = this.store.data$();
677
-
678
- // Apply active filter
679
- if (this.activeFilter() !== 'all') {
680
- const isActive = this.activeFilter() === 'active';
681
- users = users.filter(user => user.active === isActive);
682
- }
683
-
684
- // Apply role filter
685
- if (this.roleFilter()) {
686
- users = users.filter(user => user.role === this.roleFilter());
687
- }
688
-
689
- // Apply search query
690
- if (this.searchQuery()) {
691
- const query = this.searchQuery().toLowerCase();
692
- users = users.filter(user =>
693
- user.name.toLowerCase().includes(query) ||
694
- user.email.toLowerCase().includes(query)
695
- );
696
- }
697
-
698
- // Apply date range
699
- if (this.dateRange()) {
700
- const { start, end } = this.dateRange()!;
701
- users = users.filter(user => {
702
- const userDate = new Date(user.createdAt);
703
- return userDate >= start && userDate <= end;
704
- });
705
- }
706
-
707
- return users;
708
- });
709
-
710
- filterStats = computed(() => {
711
- const allUsers = this.store.data$();
712
- return {
713
- total: allUsers.length,
714
- active: allUsers.filter(u => u.active).length,
715
- inactive: allUsers.filter(u => !u.active).length,
716
- filtered: this.filteredUsers().length
717
- };
718
- });
719
-
720
- constructor() {
721
- super(
722
- ApiRequest.adapt({
723
- server: 'http://localhost:8080',
724
- path: ['users'],
725
- adapter: User.adapt
726
- }),
727
- DataType.ARRAY,
728
- DatabaseStorage.adapt({
729
- table: 'users-advanced-cache',
730
- expiresIn: '1h'
731
- })
732
- );
733
- }
734
-
735
- // Filter methods
736
- setActiveFilter(filter: 'all' | 'active' | 'inactive') {
737
- this.activeFilter.set(filter);
738
- this.fetchRecords();
739
- }
740
-
741
- setRoleFilter(role: string) {
742
- this.roleFilter.set(role);
743
- this.fetchRecords();
744
- }
745
-
746
- setSearchQuery(query: string) {
747
- this.searchQuery.set(query);
748
- // Debounced search
749
- setTimeout(() => this.fetchRecords(), 300);
750
- }
751
-
752
- setDateRange(start: Date, end: Date) {
753
- this.dateRange.set({ start, end });
754
- this.fetchRecords();
755
- }
756
-
757
- clearFilters() {
758
- this.activeFilter.set('all');
759
- this.roleFilter.set('');
760
- this.searchQuery.set('');
761
- this.dateRange.set(null);
762
- this.fetchRecords();
763
- }
764
- }
765
- ```
766
-
767
- ## Error Handling and Retry Logic
768
-
769
- ### Custom Error Handling
770
-
771
- ```typescript
772
- @Injectable()
773
- export class RobustUserStateService extends HTTPManagerStateService<User> {
774
-
775
- private retryAttempts = signal(0);
776
- private maxRetries = signal(3);
777
-
778
- constructor() {
779
- super(
780
- ApiRequest.adapt({
781
- server: 'http://localhost:8080',
782
- path: ['users'],
783
- retry: { times: 3, delay: 2 },
784
- displayError: true
785
- }),
786
- DataType.ARRAY
787
- );
788
- }
789
-
790
- // Override to add custom error handling
791
- fetchRecords(params?: any) {
792
- this.retryAttempts.set(0);
793
- super.fetchRecords(params);
794
- }
795
-
796
- // Custom retry logic for critical operations
797
- criticalUpdate(user: User) {
798
- try {
799
- this.updateRecord(user);
800
- } catch (error) {
801
- this.handleCriticalError(error, () => this.criticalUpdate(user));
802
- }
803
- }
804
-
805
- private handleCriticalError(error: any, retryFn: () => void) {
806
- const currentAttempts = this.retryAttempts();
807
- const maxAttempts = this.maxRetries();
808
-
809
- if (currentAttempts < maxAttempts) {
810
- this.retryAttempts.set(currentAttempts + 1);
811
-
812
- // Exponential backoff
813
- const delay = Math.pow(2, currentAttempts) * 1000;
814
- setTimeout(retryFn, delay);
815
- } else {
816
- // Max retries reached, show critical error
817
- this.showCriticalErrorDialog(error);
818
- }
819
- }
820
-
821
- private showCriticalErrorDialog(error: any) {
822
- // Implement your critical error handling
823
- console.error('Critical operation failed after retries:', error);
824
- }
825
- }
826
- ```
827
-
828
- ## Best Practices
829
-
830
- ### 1. Service Layer Pattern
831
-
832
- ```typescript
833
- // ✅ Good
834
- @Injectable()
835
- export class UserStateService extends HTTPManagerStateService<User> {
836
- // Business logic methods
837
- activateUser(id: number) {
838
- this.updateRecord({ id, active: true });
839
- }
840
-
841
- deactivateUser(id: number) {
842
- this.updateRecord({ id, active: false });
843
- }
844
- }
845
-
846
- // ❌ Avoid
847
- @Component({
848
- template: `<div (click)="store.updateRecord(...)">`
849
- })
850
- export class BadComponent {}
851
- ```
852
-
853
- ### 2. Proper State Management
854
-
855
- ```typescript
856
- // ✅ Good
857
- loadUsers() {
858
- this.fetchRecords(); // Uses internal state management
859
- }
860
-
861
- // ❌ Avoid
862
- loadUsers() {
863
- this.http.get('users').subscribe(users => {
864
- this.users = users; // Manual state management
865
- });
866
- }
867
- ```
868
-
869
- ### 3. WebSocket Error Handling
870
-
871
- ```typescript
872
- // ✅ Good
873
- initializeConnection(wsServer: string, jwtToken: string, user: any) {
874
- try {
875
- this.setApiRequestOptions(
876
- ApiRequest.adapt({
877
- ...this.apiRequestOptions,
878
- ws: { ...this.apiRequestOptions.ws, wsServer, jwtToken, user }
879
- })
880
- );
881
- } catch (error) {
882
- console.error('WebSocket initialization failed:', error);
883
- }
884
- }
885
- ```
886
-
887
- ### 4. Memory Management
888
-
889
- ```typescript
890
- @Component({ template: '...' })
891
- export class UserComponent implements OnDestroy {
892
- private destroy$ = new Subject<void>();
893
-
894
- ngOnInit() {
895
- this.store.data$
896
- .pipe(takeUntil(this.destroy$))
897
- .subscribe();
898
- }
899
-
900
- ngOnDestroy() {
901
- this.destroy$.next();
902
- this.destroy$.complete();
903
- }
904
- }
905
- ```
906
-
907
- ## Troubleshooting
908
-
909
- ### Common Issues
910
-
911
- #### 1. WebSocket Not Connecting
912
- ```typescript
913
- // Check configuration
914
- console.log('WS Config:', this.store.apiRequestOptions?.ws);
915
-
916
- // Verify connection
917
- this.store.connectionStatus$.subscribe(status => {
918
- console.log('WebSocket status:', status);
919
- });
920
- ```
921
-
922
- #### 2. State Not Updating
923
- ```typescript
924
- // Ensure adapter is provided for database storage
925
- ApiRequest.adapt({
926
- path: ['users'],
927
- adapter: User.adapt // Required!
928
- });
929
- ```
930
-
931
- #### 3. Infinite Loops
932
- ```typescript
933
- // Avoid calling fetchRecords() in response to WebSocket messages
934
- // The service handles this automatically
935
-
936
- // ❌ Don't do this
937
- communicationMessages$.subscribe(msg => {
938
- this.fetchRecords(); // This can cause loops
939
- });
940
- ```
941
-
942
- ## Related Documentation
943
-
944
- - [HTTP Manager Service](http-manager/README.md)
945
- - [HTTP Signals Service](http-signals/README.md)
946
- - [WebSocket Service](websocket/README.md)
947
- - [Database Manager Service](database/README.md)
948
- - [Architecture Overview](../architecture/README.md)