@techextensor/tab-core-utility 2.2.198 → 2.2.200

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 (29) hide show
  1. package/esm2022/index.mjs +5 -1
  2. package/esm2022/lib/tab-core-utility/app/constants/api-constants.mjs +3 -3
  3. package/esm2022/lib/tab-core-utility/app/constants/common.mjs +2 -1
  4. package/esm2022/lib/tab-core-utility/app/crud/tab-blueprint.service.mjs +12 -39
  5. package/esm2022/lib/tab-core-utility/app/crud/tab-release.service.mjs +9 -20
  6. package/esm2022/lib/tab-core-utility/app/enums/common.enum.mjs +12 -1
  7. package/esm2022/lib/tab-core-utility/app/interfaces/notification.interface.mjs +50 -0
  8. package/esm2022/lib/tab-core-utility/app/interfaces/release.interface.mjs +7 -0
  9. package/esm2022/lib/tab-core-utility/app/utils/req-res.util.mjs +13 -2
  10. package/esm2022/lib/tab-core-utility/core/service/notification/notification-inbox.service.mjs +269 -0
  11. package/esm2022/lib/tab-core-utility/core/service/notification/notification-websocket.service.mjs +209 -0
  12. package/esm2022/lib/tab-core-utility/core/service/signalr/operation-tracker.service.mjs +23 -6
  13. package/esm2022/lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service.mjs +53 -7
  14. package/esm2022/lib/tab-core-utility/core/service/signalr/signalr.service.mjs +21 -5
  15. package/index.d.ts +4 -0
  16. package/lib/tab-core-utility/app/constants/api-constants.d.ts +2 -2
  17. package/lib/tab-core-utility/app/constants/common.d.ts +2 -0
  18. package/lib/tab-core-utility/app/crud/tab-blueprint.service.d.ts +0 -16
  19. package/lib/tab-core-utility/app/crud/tab-release.service.d.ts +5 -12
  20. package/lib/tab-core-utility/app/enums/common.enum.d.ts +9 -0
  21. package/lib/tab-core-utility/app/interfaces/notification.interface.d.ts +154 -0
  22. package/lib/tab-core-utility/app/interfaces/release.interface.d.ts +85 -0
  23. package/lib/tab-core-utility/app/utils/req-res.util.d.ts +5 -1
  24. package/lib/tab-core-utility/core/service/notification/notification-inbox.service.d.ts +80 -0
  25. package/lib/tab-core-utility/core/service/notification/notification-websocket.service.d.ts +56 -0
  26. package/lib/tab-core-utility/core/service/signalr/operation-tracker.service.d.ts +9 -1
  27. package/lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service.d.ts +11 -0
  28. package/lib/tab-core-utility/core/service/signalr/signalr.service.d.ts +15 -3
  29. package/package.json +1 -1
@@ -0,0 +1,269 @@
1
+ import { inject, Injectable } from '@angular/core';
2
+ import { BehaviorSubject, Subject } from 'rxjs';
3
+ import { NOTIFICATION_WS_CONFIG, WS_MESSAGE_TYPE, } from '../../../app/interfaces/notification.interface';
4
+ import { NotificationWebSocketService } from './notification-websocket.service';
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * Public notification inbox service.
8
+ *
9
+ * Pure — no storage / auth coupling. The caller (SDK facade) supplies all auth
10
+ * identifiers via `connect(params)`, and they're held for the lifetime of the
11
+ * connection (cleared on disconnect).
12
+ *
13
+ * Subscribes to the WebSocket transport, routes incoming messages by type into
14
+ * dedicated streams, and exposes high-level actions for the UI.
15
+ *
16
+ * Components/extensions consume this via the SDK facade (`TabSdk.notification.*`),
17
+ * not directly.
18
+ *
19
+ * Named `NotificationInboxService` to avoid collision with the existing toastr
20
+ * `NotificationService` in `core/service/notification.service.ts`.
21
+ */
22
+ export class NotificationInboxService {
23
+ constructor() {
24
+ this.ws = inject(NotificationWebSocketService);
25
+ // Held between connect() and disconnect() — every outbound message includes it.
26
+ this.workspaceKey = null;
27
+ // ----------- streams -----------
28
+ this.latestNotifications$ = new Subject();
29
+ this.unreadCount$ = new BehaviorSubject(0);
30
+ this.markAsReadEvent$ = new Subject();
31
+ this.clearEvent$ = new Subject();
32
+ this.loading$ = new BehaviorSubject(false);
33
+ this.totalPages$ = new BehaviorSubject(1);
34
+ // Route inbound messages → streams
35
+ this.ws.messages$.subscribe((message) => this.handleMessage(message));
36
+ }
37
+ // ----------- lifecycle -----------
38
+ /**
39
+ * Connect to the notification WebSocket. Awaitable, idempotent.
40
+ *
41
+ * If a connection is already active for a *different* workspace (tenant/app/env
42
+ * switch without signOut), we tear it down first so the new connection uses
43
+ * the correct URL and workspaceKey. The underlying `ws.connect` is idempotent
44
+ * by connection state, so it would otherwise keep the stale URL.
45
+ *
46
+ * Once connected, an unread-count fetch is fired automatically so the badge populates.
47
+ */
48
+ async connect(params) {
49
+ if (this.workspaceKey && this.workspaceKey !== params.workspaceKey) {
50
+ await this.disconnect();
51
+ }
52
+ this.workspaceKey = params.workspaceKey;
53
+ await this.ws.connect({
54
+ userId: params.userId,
55
+ appId: params.appId,
56
+ tenantId: params.tenantId,
57
+ });
58
+ if (this.ws.isConnected()) {
59
+ this.requestUnreadCount();
60
+ }
61
+ }
62
+ /**
63
+ * Tear down the connection. Resets all stream state so the UI clears.
64
+ */
65
+ async disconnect() {
66
+ await this.ws.disconnect();
67
+ this.workspaceKey = null;
68
+ this.unreadCount$.next(0);
69
+ this.totalPages$.next(1);
70
+ this.loading$.next(false);
71
+ }
72
+ // ----------- actions -----------
73
+ /**
74
+ * Fetch a page of notifications. Server replies via GET_NOTIFICATIONS_RESPONSE.
75
+ */
76
+ loadMore(pageNumber, pageSize = NOTIFICATION_WS_CONFIG.DEFAULT_PAGE_SIZE) {
77
+ if (!this.workspaceKey)
78
+ return;
79
+ this.loading$.next(true);
80
+ this.ws.send({
81
+ type: WS_MESSAGE_TYPE.GET_NOTIFICATIONS,
82
+ workspaceKey: this.workspaceKey,
83
+ pageNumber,
84
+ pageSize,
85
+ });
86
+ }
87
+ /**
88
+ * Request unread count. Result arrives on `unreadCount$`.
89
+ */
90
+ requestUnreadCount() {
91
+ if (!this.workspaceKey)
92
+ return;
93
+ this.ws.send({
94
+ type: WS_MESSAGE_TYPE.GET_UNREAD_COUNT,
95
+ workspaceKey: this.workspaceKey,
96
+ });
97
+ }
98
+ markAsRead(notificationId) {
99
+ if (!this.workspaceKey)
100
+ return;
101
+ this.ws.send({
102
+ type: WS_MESSAGE_TYPE.MARK_NOTIFICATION_READ,
103
+ workspaceKey: this.workspaceKey,
104
+ notificationId,
105
+ });
106
+ }
107
+ markAllAsRead() {
108
+ if (!this.workspaceKey)
109
+ return;
110
+ this.ws.send({
111
+ type: WS_MESSAGE_TYPE.MARK_ALL_NOTIFICATION_READ,
112
+ workspaceKey: this.workspaceKey,
113
+ });
114
+ }
115
+ clearOne(notificationId) {
116
+ if (!this.workspaceKey)
117
+ return;
118
+ this.ws.send({
119
+ type: WS_MESSAGE_TYPE.CLEAR_NOTIFICATION,
120
+ workspaceKey: this.workspaceKey,
121
+ notificationId,
122
+ });
123
+ }
124
+ clearAll() {
125
+ if (!this.workspaceKey)
126
+ return;
127
+ this.ws.send({
128
+ type: WS_MESSAGE_TYPE.CLEAR_ALL_NOTIFICATIONS,
129
+ workspaceKey: this.workspaceKey,
130
+ });
131
+ }
132
+ // ----------- streams (read-only views) -----------
133
+ getLatestNotifications() {
134
+ return this.latestNotifications$.asObservable();
135
+ }
136
+ getUnreadCount() {
137
+ return this.unreadCount$.asObservable();
138
+ }
139
+ getMarkAsReadEvents() {
140
+ return this.markAsReadEvent$.asObservable();
141
+ }
142
+ getClearEvents() {
143
+ return this.clearEvent$.asObservable();
144
+ }
145
+ getLoadingState() {
146
+ return this.loading$.asObservable();
147
+ }
148
+ getTotalPages() {
149
+ return this.totalPages$.asObservable();
150
+ }
151
+ // ----------- internal -----------
152
+ handleMessage(message) {
153
+ if (!message?.type)
154
+ return;
155
+ switch (message.type) {
156
+ case WS_MESSAGE_TYPE.GET_NOTIFICATIONS_RESPONSE:
157
+ if (message.success) {
158
+ const items = message.notifications ?? [];
159
+ const ui = items.map((n) => this.parseInboxNotification(n));
160
+ this.latestNotifications$.next(ui);
161
+ this.totalPages$.next(message.totalPages ?? 1);
162
+ }
163
+ this.loading$.next(false);
164
+ break;
165
+ case WS_MESSAGE_TYPE.GET_UNREAD_COUNT_RESPONSE:
166
+ if (message.success) {
167
+ this.unreadCount$.next(message.count ?? 0);
168
+ }
169
+ break;
170
+ case WS_MESSAGE_TYPE.NOTIFICATION: {
171
+ const ui = this.transformPushNotification(message);
172
+ this.latestNotifications$.next(ui);
173
+ this.requestUnreadCount();
174
+ break;
175
+ }
176
+ case WS_MESSAGE_TYPE.MARK_NOTIFICATION_READ_RESPONSE:
177
+ if (message.success) {
178
+ this.markAsReadEvent$.next(message.notificationId ?? null);
179
+ this.requestUnreadCount();
180
+ }
181
+ break;
182
+ case WS_MESSAGE_TYPE.NOTIFICATION_MARKED_READ:
183
+ // Broadcast from another session of same user. notificationId optional
184
+ // (absent ⇒ "all read").
185
+ this.markAsReadEvent$.next(message.notificationId ?? null);
186
+ this.requestUnreadCount();
187
+ break;
188
+ case WS_MESSAGE_TYPE.MARK_ALL_NOTIFICATION_READ_RESPONSE:
189
+ if (message.success) {
190
+ this.markAsReadEvent$.next(null);
191
+ this.requestUnreadCount();
192
+ }
193
+ break;
194
+ case WS_MESSAGE_TYPE.CLEAR_NOTIFICATION_RESPONSE:
195
+ case WS_MESSAGE_TYPE.NOTIFICATION_CLEARED:
196
+ if (Array.isArray(message.notificationIds) && message.notificationIds.length) {
197
+ this.clearEvent$.next(message.notificationIds);
198
+ this.requestUnreadCount();
199
+ }
200
+ break;
201
+ case WS_MESSAGE_TYPE.CLEAR_ALL_NOTIFICATIONS_RESPONSE:
202
+ if (message.success) {
203
+ this.clearEvent$.next(null);
204
+ this.requestUnreadCount();
205
+ }
206
+ break;
207
+ case WS_MESSAGE_TYPE.ALL_NOTIFICATIONS_CLEARED:
208
+ if (message.success) {
209
+ this.clearEvent$.next(null);
210
+ this.requestUnreadCount();
211
+ }
212
+ break;
213
+ // CONNECTION_ESTABLISHED, PONG, HEARTBEAT_ACK, ERROR are handled at the
214
+ // transport layer (or are no-ops). HEARTBEAT is intercepted by transport
215
+ // and never forwarded.
216
+ }
217
+ }
218
+ /**
219
+ * Parse an inbox notification's `data` JSON into a UI-shaped object.
220
+ *
221
+ * Read state is surfaced via `status === 'Read'` (confirmed by BE).
222
+ * Inbox response only contains `Delivered` (unread) + `Read` items;
223
+ * `Pending` / `Done` / `Failed` are filtered out server-side.
224
+ */
225
+ parseInboxNotification(item) {
226
+ let parsedPayload = {};
227
+ try {
228
+ parsedPayload = JSON.parse(item.data);
229
+ }
230
+ catch {
231
+ parsedPayload = {};
232
+ }
233
+ return {
234
+ id: item.id,
235
+ createdAt: item.createdAt,
236
+ status: item.status,
237
+ priority: item.priority,
238
+ parsedPayload,
239
+ isRead: item.status === 'Read',
240
+ };
241
+ }
242
+ /**
243
+ * Wrap a server-pushed live notification into the same UI shape as inbox items.
244
+ * The push event has fields flat at the top level (NOT inside `data`) — synthesize
245
+ * `parsedPayload` from those fields so the component sees a uniform shape.
246
+ */
247
+ transformPushNotification(push) {
248
+ return {
249
+ id: push.id,
250
+ createdAt: push.createdAt,
251
+ status: 'Delivered',
252
+ priority: push.priority,
253
+ parsedPayload: {
254
+ title: push.title,
255
+ body: push.body,
256
+ category: push.category,
257
+ priority: push.priority,
258
+ },
259
+ isRead: false,
260
+ };
261
+ }
262
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: NotificationInboxService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
263
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: NotificationInboxService, providedIn: 'root' }); }
264
+ }
265
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: NotificationInboxService, decorators: [{
266
+ type: Injectable,
267
+ args: [{ providedIn: 'root' }]
268
+ }], ctorParameters: () => [] });
269
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90aWZpY2F0aW9uLWluYm94LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2RhdGEtYWNjZXNzL3NyYy9saWIvdGFiLWNvcmUtdXRpbGl0eS9jb3JlL3NlcnZpY2Uvbm90aWZpY2F0aW9uL25vdGlmaWNhdGlvbi1pbmJveC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxlQUFlLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVELE9BQU8sRUFDTCxzQkFBc0IsRUFNdEIsZUFBZSxHQUNoQixNQUFNLGdEQUFnRCxDQUFDO0FBQ3hELE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDOztBQUVoRjs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxNQUFNLE9BQU8sd0JBQXdCO0lBZW5DO1FBZGlCLE9BQUUsR0FBRyxNQUFNLENBQUMsNEJBQTRCLENBQUMsQ0FBQztRQUUzRCxnRkFBZ0Y7UUFDeEUsaUJBQVksR0FBa0IsSUFBSSxDQUFDO1FBRTNDLGtDQUFrQztRQUVqQix5QkFBb0IsR0FBRyxJQUFJLE9BQU8sRUFBcUMsQ0FBQztRQUN4RSxpQkFBWSxHQUFHLElBQUksZUFBZSxDQUFTLENBQUMsQ0FBQyxDQUFDO1FBQzlDLHFCQUFnQixHQUFHLElBQUksT0FBTyxFQUFpQixDQUFDO1FBQ2hELGdCQUFXLEdBQUcsSUFBSSxPQUFPLEVBQW1CLENBQUM7UUFDN0MsYUFBUSxHQUFHLElBQUksZUFBZSxDQUFVLEtBQUssQ0FBQyxDQUFDO1FBQy9DLGdCQUFXLEdBQUcsSUFBSSxlQUFlLENBQVMsQ0FBQyxDQUFDLENBQUM7UUFHNUQsbUNBQW1DO1FBQ25DLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxD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bUhBQXhCLHdCQUF3QixjQURYLE1BQU07OzRGQUNuQix3QkFBd0I7a0JBRHBDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQge1xyXG4gIE5PVElGSUNBVElPTl9XU19DT05GSUcsXHJcbiAgTm90aWZpY2F0aW9uSW5ib3hDb25uZWN0UGFyYW1zLFxyXG4gIE5vdGlmaWNhdGlvbkl0ZW0sXHJcbiAgTm90aWZpY2F0aW9uUHVzaFBheWxvYWQsXHJcbiAgUGFyc2VkTm90aWZpY2F0aW9uUGF5bG9hZCxcclxuICBVaU5vdGlmaWNhdGlvbixcclxuICBXU19NRVNTQUdFX1RZUEUsXHJcbn0gZnJvbSAnLi4vLi4vLi4vYXBwL2ludGVyZmFjZXMvbm90aWZpY2F0aW9uLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IE5vdGlmaWNhdGlvbldlYlNvY2tldFNlcnZpY2UgfSBmcm9tICcuL25vdGlmaWNhdGlvbi13ZWJzb2NrZXQuc2VydmljZSc7XHJcblxyXG4vKipcclxuICogUHVibGljIG5vdGlmaWNhdGlvbiBpbmJveCBzZXJ2aWNlLlxyXG4gKlxyXG4gKiBQdXJlIOKAlCBubyBzdG9yYWdlIC8gYXV0aCBjb3VwbGluZy4gVGhlIGNhbGxlciAoU0RLIGZhY2FkZSkgc3VwcGxpZXMgYWxsIGF1dGhcclxuICogaWRlbnRpZmllcnMgdmlhIGBjb25uZWN0KHBhcmFtcylgLCBhbmQgdGhleSdyZSBoZWxkIGZvciB0aGUgbGlmZXRpbWUgb2YgdGhlXHJcbiAqIGNvbm5lY3Rpb24gKGNsZWFyZWQgb24gZGlzY29ubmVjdCkuXHJcbiAqXHJcbiAqIFN1YnNjcmliZXMgdG8gdGhlIFdlYlNvY2tldCB0cmFuc3BvcnQsIHJvdXRlcyBpbmNvbWluZyBtZXNzYWdlcyBieSB0eXBlIGludG9cclxuICogZGVkaWNhdGVkIHN0cmVhbXMsIGFuZCBleHBvc2VzIGhpZ2gtbGV2ZWwgYWN0aW9ucyBmb3IgdGhlIFVJLlxyXG4gKlxyXG4gKiBDb21wb25lbnRzL2V4dGVuc2lvbnMgY29uc3VtZSB0aGlzIHZpYSB0aGUgU0RLIGZhY2FkZSAoYFRhYlNkay5ub3RpZmljYXRpb24uKmApLFxyXG4gKiBub3QgZGlyZWN0bHkuXHJcbiAqXHJcbiAqIE5hbWVkIGBOb3RpZmljYXRpb25JbmJveFNlcnZpY2VgIHRvIGF2b2lkIGNvbGxpc2lvbiB3aXRoIHRoZSBleGlzdGluZyB0b2FzdHJcclxuICogYE5vdGlmaWNhdGlvblNlcnZpY2VgIGluIGBjb3JlL3NlcnZpY2Uvbm90aWZpY2F0aW9uLnNlcnZpY2UudHNgLlxyXG4gKi9cclxuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcclxuZXhwb3J0IGNsYXNzIE5vdGlmaWNhdGlvbkluYm94U2VydmljZSB7XHJcbiAgcHJpdmF0ZSByZWFkb25seSB3cyA9IGluamVjdChOb3RpZmljYXRpb25XZWJTb2NrZXRTZXJ2aWNlKTtcclxuXHJcbiAgLy8gSGVsZCBiZXR3ZWVuIGNvbm5lY3QoKSBhbmQgZGlzY29ubmVjdCgpIOKAlCBldmVyeSBvdXRib3VuZCBtZXNzYWdlIGluY2x1ZGVzIGl0LlxyXG4gIHByaXZhdGUgd29ya3NwYWNlS2V5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLy8gLS0tLS0tLS0tLS0gc3RyZWFtcyAtLS0tLS0tLS0tLVxyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IGxhdGVzdE5vdGlmaWNhdGlvbnMkID0gbmV3IFN1YmplY3Q8VWlOb3RpZmljYXRpb24gfCBVaU5vdGlmaWNhdGlvbltdPigpO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgdW5yZWFkQ291bnQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KDApO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgbWFya0FzUmVhZEV2ZW50JCA9IG5ldyBTdWJqZWN0PHN0cmluZyB8IG51bGw+KCk7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBjbGVhckV2ZW50JCA9IG5ldyBTdWJqZWN0PHN0cmluZ1tdIHwgbnVsbD4oKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IGxvYWRpbmckID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XHJcbiAgcHJpdmF0ZSByZWFkb25seSB0b3RhbFBhZ2VzJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPigxKTtcclxuXHJcbiAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAvLyBSb3V0ZSBpbmJvdW5kIG1lc3NhZ2VzIOKGkiBzdHJlYW1zXHJcbiAgICB0aGlzLndzLm1lc3NhZ2VzJC5zdWJzY3JpYmUoKG1lc3NhZ2UpID0+IHRoaXMuaGFuZGxlTWVzc2FnZShtZXNzYWdlKSk7XHJcbiAgfVxyXG5cclxuICAvLyAtLS0tLS0tLS0tLSBsaWZlY3ljbGUgLS0tLS0tLS0tLS1cclxuXHJcbiAgLyoqXHJcbiAgICogQ29ubmVjdCB0byB0aGUgbm90aWZpY2F0aW9uIFdlYlNvY2tldC4gQXdhaXRhYmxlLCBpZGVtcG90ZW50LlxyXG4gICAqXHJcbiAgICogSWYgYSBjb25uZWN0aW9uIGlzIGFscmVhZHkgYWN0aXZlIGZvciBhICpkaWZmZXJlbnQqIHdvcmtzcGFjZSAodGVuYW50L2FwcC9lbnZcclxuICAgKiBzd2l0Y2ggd2l0aG91dCBzaWduT3V0KSwgd2UgdGVhciBpdCBkb3duIGZpcnN0IHNvIHRoZSBuZXcgY29ubmVjdGlvbiB1c2VzXHJcbiAgICogdGhlIGNvcnJlY3QgVVJMIGFuZCB3b3Jrc3BhY2VLZXkuIFRoZSB1bmRlcmx5aW5nIGB3cy5jb25uZWN0YCBpcyBpZGVtcG90ZW50XHJcbiAgICogYnkgY29ubmVjdGlvbiBzdGF0ZSwgc28gaXQgd291bGQgb3RoZXJ3aXNlIGtlZXAgdGhlIHN0YWxlIFVSTC5cclxuICAgKlxyXG4gICAqIE9uY2UgY29ubmVjdGVkLCBhbiB1bnJlYWQtY291bnQgZmV0Y2ggaXMgZmlyZWQgYXV0b21hdGljYWxseSBzbyB0aGUgYmFkZ2UgcG9wdWxhdGVzLlxyXG4gICAqL1xyXG4gIGFzeW5jIGNvbm5lY3QocGFyYW1zOiBOb3RpZmljYXRpb25JbmJveENvbm5lY3RQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICh0aGlzLndvcmtzcGFjZUtleSAmJiB0aGlzLndvcmtzcGFjZUtleSAhPT0gcGFyYW1zLndvcmtzcGFjZUtleSkge1xyXG4gICAgICBhd2FpdCB0aGlzLmRpc2Nvbm5lY3QoKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLndvcmtzcGFjZUtleSA9IHBhcmFtcy53b3Jrc3BhY2VLZXk7XHJcblxyXG4gICAgYXdhaXQgdGhpcy53cy5jb25uZWN0KHtcclxuICAgICAgdXNlcklkOiBwYXJhbXMudXNlcklkLFxyXG4gICAgICBhcHBJZDogcGFyYW1zLmFwcElkLFxyXG4gICAgICB0ZW5hbnRJZDogcGFyYW1zLnRlbmFudElkLFxyXG4gICAgfSk7XHJcblxyXG4gICAgaWYgKHRoaXMud3MuaXNDb25uZWN0ZWQoKSkge1xyXG4gICAgICB0aGlzLnJlcXVlc3RVbnJlYWRDb3VudCgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVGVhciBkb3duIHRoZSBjb25uZWN0aW9uLiBSZXNldHMgYWxsIHN0cmVhbSBzdGF0ZSBzbyB0aGUgVUkgY2xlYXJzLlxyXG4gICAqL1xyXG4gIGFzeW5jIGRpc2Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBhd2FpdCB0aGlzLndzLmRpc2Nvbm5lY3QoKTtcclxuICAgIHRoaXMud29ya3NwYWNlS2V5ID0gbnVsbDtcclxuICAgIHRoaXMudW5yZWFkQ291bnQkLm5leHQoMCk7XHJcbiAgICB0aGlzLnRvdGFsUGFnZXMkLm5leHQoMSk7XHJcbiAgICB0aGlzLmxvYWRpbmckLm5leHQoZmFsc2UpO1xyXG4gIH1cclxuXHJcbiAgLy8gLS0tLS0tLS0tLS0gYWN0aW9ucyAtLS0tLS0tLS0tLVxyXG5cclxuICAvKipcclxuICAgKiBGZXRjaCBhIHBhZ2Ugb2Ygbm90aWZpY2F0aW9ucy4gU2VydmVyIHJlcGxpZXMgdmlhIEdFVF9OT1RJRklDQVRJT05TX1JFU1BPTlNFLlxyXG4gICAqL1xyXG4gIGxvYWRNb3JlKHBhZ2VOdW1iZXI6IG51bWJlciwgcGFnZVNpemU6IG51bWJlciA9IE5PVElGSUNBVElPTl9XU19DT05GSUcuREVGQVVMVF9QQUdFX1NJWkUpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy53b3Jrc3BhY2VLZXkpIHJldHVybjtcclxuICAgIHRoaXMubG9hZGluZyQubmV4dCh0cnVlKTtcclxuICAgIHRoaXMud3Muc2VuZCh7XHJcbiAgICAgIHR5cGU6IFdTX01FU1NBR0VfVFlQRS5HRVRfTk9USUZJQ0FUSU9OUyxcclxuICAgICAgd29ya3NwYWNlS2V5OiB0aGlzLndvcmtzcGFjZUtleSxcclxuICAgICAgcGFnZU51bWJlcixcclxuICAgICAgcGFnZVNpemUsXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlcXVlc3QgdW5yZWFkIGNvdW50LiBSZXN1bHQgYXJyaXZlcyBvbiBgdW5yZWFkQ291bnQkYC5cclxuICAgKi9cclxuICByZXF1ZXN0VW5yZWFkQ291bnQoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMud29ya3NwYWNlS2V5KSByZXR1cm47XHJcbiAgICB0aGlzLndzLnNlbmQoe1xyXG4gICAgICB0eXBlOiBXU19NRVNTQUdFX1RZUEUuR0VUX1VOUkVBRF9DT1VOVCxcclxuICAgICAgd29ya3NwYWNlS2V5OiB0aGlzLndvcmtzcGFjZUtleSxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbWFya0FzUmVhZChub3RpZmljYXRpb25JZDogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMud29ya3NwYWNlS2V5KSByZXR1cm47XHJcbiAgICB0aGlzLndzLnNlbmQoe1xyXG4gICAgICB0eXBlOiBXU19NRVNTQUdFX1RZUEUuTUFSS19OT1RJRklDQVRJT05fUkVBRCxcclxuICAgICAgd29ya3NwYWNlS2V5OiB0aGlzLndvcmtzcGFjZUtleSxcclxuICAgICAgbm90aWZpY2F0aW9uSWQsXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIG1hcmtBbGxBc1JlYWQoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMud29ya3NwYWNlS2V5KSByZXR1cm47XHJcbiAgICB0aGlzLndzLnNlbmQoe1xyXG4gICAgICB0eXBlOiBXU19NRVNTQUdFX1RZUEUuTUFSS19BTExfTk9USUZJQ0FUSU9OX1JFQUQsXHJcbiAgICAgIHdvcmtzcGFjZUtleTogdGhpcy53b3Jrc3BhY2VLZXksXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGNsZWFyT25lKG5vdGlmaWNhdGlvbklkOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy53b3Jrc3BhY2VLZXkpIHJldHVybjtcclxuICAgIHRoaXMud3Muc2VuZCh7XHJcbiAgICAgIHR5cGU6IFdTX01FU1NBR0VfVFlQRS5DTEVBUl9OT1RJRklDQVRJT04sXHJcbiAgICAgIHdvcmtzcGFjZUtleTogdGhpcy53b3Jrc3BhY2VLZXksXHJcbiAgICAgIG5vdGlmaWNhdGlvbklkLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBjbGVhckFsbCgpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy53b3Jrc3BhY2VLZXkpIHJldHVybjtcclxuICAgIHRoaXMud3Muc2VuZCh7XHJcbiAgICAgIHR5cGU6IFdTX01FU1NBR0VfVFlQRS5DTEVBUl9BTExfTk9USUZJQ0FUSU9OUyxcclxuICAgICAgd29ya3NwYWNlS2V5OiB0aGlzLndvcmtzcGFjZUtleSxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLy8gLS0tLS0tLS0tLS0gc3RyZWFtcyAocmVhZC1vbmx5IHZpZXdzKSAtLS0tLS0tLS0tLVxyXG5cclxuICBnZXRMYXRlc3ROb3RpZmljYXRpb25zKCk6IE9ic2VydmFibGU8VWlOb3RpZmljYXRpb24gfCBVaU5vdGlmaWNhdGlvbltdPiB7XHJcbiAgICByZXR1cm4gdGhpcy5sYXRlc3ROb3RpZmljYXRpb25zJC5hc09ic2VydmFibGUoKTtcclxuICB9XHJcblxyXG4gIGdldFVucmVhZENvdW50KCk6IE9ic2VydmFibGU8bnVtYmVyPiB7XHJcbiAgICByZXR1cm4gdGhpcy51bnJlYWRDb3VudCQuYXNPYnNlcnZhYmxlKCk7XHJcbiAgfVxyXG5cclxuICBnZXRNYXJrQXNSZWFkRXZlbnRzKCk6IE9ic2VydmFibGU8c3RyaW5nIHwgbnVsbD4ge1xyXG4gICAgcmV0dXJuIHRoaXMubWFya0FzUmVhZEV2ZW50JC5hc09ic2VydmFibGUoKTtcclxuICB9XHJcblxyXG4gIGdldENsZWFyRXZlbnRzKCk6IE9ic2VydmFibGU8c3RyaW5nW10gfCBudWxsPiB7XHJcbiAgICByZXR1cm4gdGhpcy5jbGVhckV2ZW50JC5hc09ic2VydmFibGUoKTtcclxuICB9XHJcblxyXG4gIGdldExvYWRpbmdTdGF0ZSgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcclxuICAgIHJldHVybiB0aGlzLmxvYWRpbmckLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIH1cclxuXHJcbiAgZ2V0VG90YWxQYWdlcygpOiBPYnNlcnZhYmxlPG51bWJlcj4ge1xyXG4gICAgcmV0dXJuIHRoaXMudG90YWxQYWdlcyQuYXNPYnNlcnZhYmxlKCk7XHJcbiAgfVxyXG5cclxuICAvLyAtLS0tLS0tLS0tLSBpbnRlcm5hbCAtLS0tLS0tLS0tLVxyXG5cclxuICBwcml2YXRlIGhhbmRsZU1lc3NhZ2UobWVzc2FnZTogYW55KTogdm9pZCB7XHJcbiAgICBpZiAoIW1lc3NhZ2U/LnR5cGUpIHJldHVybjtcclxuXHJcbiAgICBzd2l0Y2ggKG1lc3NhZ2UudHlwZSkge1xyXG4gICAgICBjYXNlIFdTX01FU1NBR0VfVFlQRS5HRVRfTk9USUZJQ0FUSU9OU19SRVNQT05TRTpcclxuICAgICAgICBpZiAobWVzc2FnZS5zdWNjZXNzKSB7XHJcbiAgICAgICAgICBjb25zdCBpdGVtczogTm90aWZpY2F0aW9uSXRlbVtdID0gbWVzc2FnZS5ub3RpZmljYXRpb25zID8/IFtdO1xyXG4gICAgICAgICAgY29uc3QgdWkgPSBpdGVtcy5tYXAoKG4pID0+IHRoaXMucGFyc2VJbmJveE5vdGlmaWNhdGlvbihuKSk7XHJcbiAgICAgICAgICB0aGlzLmxhdGVzdE5vdGlmaWNhdGlvbnMkLm5leHQodWkpO1xyXG4gICAgICAgICAgdGhpcy50b3RhbFBhZ2VzJC5uZXh0KG1lc3NhZ2UudG90YWxQYWdlcyA/PyAxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5sb2FkaW5nJC5uZXh0KGZhbHNlKTtcclxuICAgICAgICBicmVhaztcclxuXHJcbiAgICAgIGNhc2UgV1NfTUVTU0FHRV9UWVBFLkdFVF9VTlJFQURfQ09VTlRfUkVTUE9OU0U6XHJcbiAgICAgICAgaWYgKG1lc3NhZ2Uuc3VjY2Vzcykge1xyXG4gICAgICAgICAgdGhpcy51bnJlYWRDb3VudCQubmV4dChtZXNzYWdlLmNvdW50ID8/IDApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBicmVhaztcclxuXHJcbiAgICAgIGNhc2UgV1NfTUVTU0FHRV9UWVBFLk5PVElGSUNBVElPTjoge1xyXG4gICAgICAgIGNvbnN0IHVpID0gdGhpcy50cmFuc2Zvcm1QdXNoTm90aWZpY2F0aW9uKG1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMubGF0ZXN0Tm90aWZpY2F0aW9ucyQubmV4dCh1aSk7XHJcbiAgICAgICAgdGhpcy5yZXF1ZXN0VW5yZWFkQ291bnQoKTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG5cclxuICAgICAgY2FzZSBXU19NRVNTQUdFX1RZUEUuTUFSS19OT1RJRklDQVRJT05fUkVBRF9SRVNQT05TRTpcclxuICAgICAgICBpZiAobWVzc2FnZS5zdWNjZXNzKSB7XHJcbiAgICAgICAgICB0aGlzLm1hcmtBc1JlYWRFdmVudCQubmV4dChtZXNzYWdlLm5vdGlmaWNhdGlvbklkID8/IG51bGwpO1xyXG4gICAgICAgICAgdGhpcy5yZXF1ZXN0VW5yZWFkQ291bnQoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICBjYXNlIFdTX01FU1NBR0VfVFlQRS5OT1RJRklDQVRJT05fTUFSS0VEX1JFQUQ6XHJcbiAgICAgICAgLy8gQnJvYWRjYXN0IGZyb20gYW5vdGhlciBzZXNzaW9uIG9mIHNhbWUgdXNlci4gbm90aWZpY2F0aW9uSWQgb3B0aW9uYWxcclxuICAgICAgICAvLyAoYWJzZW50IOKHkiBcImFsbCByZWFkXCIpLlxyXG4gICAgICAgIHRoaXMubWFya0FzUmVhZEV2ZW50JC5uZXh0KG1lc3NhZ2Uubm90aWZpY2F0aW9uSWQgPz8gbnVsbCk7XHJcbiAgICAgICAgdGhpcy5yZXF1ZXN0VW5yZWFkQ291bnQoKTtcclxuICAgICAgICBicmVhaztcclxuXHJcbiAgICAgIGNhc2UgV1NfTUVTU0FHRV9UWVBFLk1BUktfQUxMX05PVElGSUNBVElPTl9SRUFEX1JFU1BPTlNFOlxyXG4gICAgICAgIGlmIChtZXNzYWdlLnN1Y2Nlc3MpIHtcclxuICAgICAgICAgIHRoaXMubWFya0FzUmVhZEV2ZW50JC5uZXh0KG51bGwpO1xyXG4gICAgICAgICAgdGhpcy5yZXF1ZXN0VW5yZWFkQ291bnQoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICBjYXNlIFdTX01FU1NBR0VfVFlQRS5DTEVBUl9OT1RJRklDQVRJT05fUkVTUE9OU0U6XHJcbiAgICAgIGNhc2UgV1NfTUVTU0FHRV9UWVBFLk5PVElGSUNBVElPTl9DTEVBUkVEOlxyXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KG1lc3NhZ2Uubm90aWZpY2F0aW9uSWRzKSAmJiBtZXNzYWdlLm5vdGlmaWNhdGlvbklkcy5sZW5ndGgpIHtcclxuICAgICAgICAgIHRoaXMuY2xlYXJFdmVudCQubmV4dChtZXNzYWdlLm5vdGlmaWNhdGlvbklkcyk7XHJcbiAgICAgICAgICB0aGlzLnJlcXVlc3RVbnJlYWRDb3VudCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBicmVhaztcclxuXHJcbiAgICAgIGNhc2UgV1NfTUVTU0FHRV9UWVBFLkNMRUFSX0FMTF9OT1RJRklDQVRJT05TX1JFU1BPTlNFOlxyXG4gICAgICAgIGlmIChtZXNzYWdlLnN1Y2Nlc3MpIHtcclxuICAgICAgICAgIHRoaXMuY2xlYXJFdmVudCQubmV4dChudWxsKTtcclxuICAgICAgICAgIHRoaXMucmVxdWVzdFVucmVhZENvdW50KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgY2FzZSBXU19NRVNTQUdFX1RZUEUuQUxMX05PVElGSUNBVElPTlNfQ0xFQVJFRDpcclxuICAgICAgICBpZiAobWVzc2FnZS5zdWNjZXNzKSB7XHJcbiAgICAgICAgICB0aGlzLmNsZWFyRXZlbnQkLm5leHQobnVsbCk7XHJcbiAgICAgICAgICB0aGlzLnJlcXVlc3RVbnJlYWRDb3VudCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBicmVhaztcclxuXHJcbiAgICAgIC8vIENPTk5FQ1RJT05fRVNUQUJMSVNIRUQsIFBPTkcsIEhFQVJUQkVBVF9BQ0ssIEVSUk9SIGFyZSBoYW5kbGVkIGF0IHRoZVxyXG4gICAgICAvLyB0cmFuc3BvcnQgbGF5ZXIgKG9yIGFyZSBuby1vcHMpLiBIRUFSVEJFQVQgaXMgaW50ZXJjZXB0ZWQgYnkgdHJhbnNwb3J0XHJcbiAgICAgIC8vIGFuZCBuZXZlciBmb3J3YXJkZWQuXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBQYXJzZSBhbiBpbmJveCBub3RpZmljYXRpb24ncyBgZGF0YWAgSlNPTiBpbnRvIGEgVUktc2hhcGVkIG9iamVjdC5cclxuICAgKlxyXG4gICAqIFJlYWQgc3RhdGUgaXMgc3VyZmFjZWQgdmlhIGBzdGF0dXMgPT09ICdSZWFkJ2AgKGNvbmZpcm1lZCBieSBCRSkuXHJcbiAgICogSW5ib3ggcmVzcG9uc2Ugb25seSBjb250YWlucyBgRGVsaXZlcmVkYCAodW5yZWFkKSArIGBSZWFkYCBpdGVtcztcclxuICAgKiBgUGVuZGluZ2AgLyBgRG9uZWAgLyBgRmFpbGVkYCBhcmUgZmlsdGVyZWQgb3V0IHNlcnZlci1zaWRlLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgcGFyc2VJbmJveE5vdGlmaWNhdGlvbihpdGVtOiBOb3RpZmljYXRpb25JdGVtKTogVWlOb3RpZmljYXRpb24ge1xyXG4gICAgbGV0IHBhcnNlZFBheWxvYWQ6IFBhcnNlZE5vdGlmaWNhdGlvblBheWxvYWQgPSB7fTtcclxuICAgIHRyeSB7XHJcbiAgICAgIHBhcnNlZFBheWxvYWQgPSBKU09OLnBhcnNlKGl0ZW0uZGF0YSkgYXMgUGFyc2VkTm90aWZpY2F0aW9uUGF5bG9hZDtcclxuICAgIH0gY2F0Y2gge1xyXG4gICAgICBwYXJzZWRQYXlsb2FkID0ge307XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgaWQ6IGl0ZW0uaWQsXHJcbiAgICAgIGNyZWF0ZWRBdDogaXRlbS5jcmVhdGVkQXQsXHJcbiAgICAgIHN0YXR1czogaXRlbS5zdGF0dXMsXHJcbiAgICAgIHByaW9yaXR5OiBpdGVtLnByaW9yaXR5LFxyXG4gICAgICBwYXJzZWRQYXlsb2FkLFxyXG4gICAgICBpc1JlYWQ6IGl0ZW0uc3RhdHVzID09PSAnUmVhZCcsXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogV3JhcCBhIHNlcnZlci1wdXNoZWQgbGl2ZSBub3RpZmljYXRpb24gaW50byB0aGUgc2FtZSBVSSBzaGFwZSBhcyBpbmJveCBpdGVtcy5cclxuICAgKiBUaGUgcHVzaCBldmVudCBoYXMgZmllbGRzIGZsYXQgYXQgdGhlIHRvcCBsZXZlbCAoTk9UIGluc2lkZSBgZGF0YWApIOKAlCBzeW50aGVzaXplXHJcbiAgICogYHBhcnNlZFBheWxvYWRgIGZyb20gdGhvc2UgZmllbGRzIHNvIHRoZSBjb21wb25lbnQgc2VlcyBhIHVuaWZvcm0gc2hhcGUuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSB0cmFuc2Zvcm1QdXNoTm90aWZpY2F0aW9uKHB1c2g6IE5vdGlmaWNhdGlvblB1c2hQYXlsb2FkKTogVWlOb3RpZmljYXRpb24ge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgaWQ6IHB1c2guaWQsXHJcbiAgICAgIGNyZWF0ZWRBdDogcHVzaC5jcmVhdGVkQXQsXHJcbiAgICAgIHN0YXR1czogJ0RlbGl2ZXJlZCcsXHJcbiAgICAgIHByaW9yaXR5OiBwdXNoLnByaW9yaXR5LFxyXG4gICAgICBwYXJzZWRQYXlsb2FkOiB7XHJcbiAgICAgICAgdGl0bGU6IHB1c2gudGl0bGUsXHJcbiAgICAgICAgYm9keTogcHVzaC5ib2R5LFxyXG4gICAgICAgIGNhdGVnb3J5OiBwdXNoLmNhdGVnb3J5LFxyXG4gICAgICAgIHByaW9yaXR5OiBwdXNoLnByaW9yaXR5LFxyXG4gICAgICB9LFxyXG4gICAgICBpc1JlYWQ6IGZhbHNlLFxyXG4gICAgfTtcclxuICB9XHJcbn1cclxuIl19
@@ -0,0 +1,209 @@
1
+ import { Injectable, signal } from '@angular/core';
2
+ import { Subject } from 'rxjs';
3
+ import { webSocket } from 'rxjs/webSocket';
4
+ import { Common } from '../../../app/constants/common';
5
+ import { NOTIFICATION_WS_CONFIG, WS_CONNECTION_STATE, WS_MESSAGE_TYPE, } from '../../../app/interfaces/notification.interface';
6
+ import * as i0 from "@angular/core";
7
+ /**
8
+ * Low-level Notification WebSocket transport.
9
+ *
10
+ * Pure — no storage / auth coupling. The caller (SDK facade or app layer)
11
+ * supplies all auth identifiers via `connect(params)`.
12
+ *
13
+ * Mirrors the SignalR infrastructure pattern:
14
+ * - connect() is idempotent, dedupes concurrent calls, tears down stale sockets
15
+ * - disconnect() flips an explicit-disconnected flag so retries don't revive
16
+ * - state exposed as Angular signal
17
+ * - inbound messages forwarded on `messages$` for higher-level service to route
18
+ *
19
+ * Internal use — consumers should use `NotificationInboxService` instead.
20
+ */
21
+ export class NotificationWebSocketService {
22
+ constructor() {
23
+ this.socket = null;
24
+ this.socketSub = null;
25
+ // In-flight connect promise — used to dedupe concurrent connect() calls
26
+ this.connectingPromise = null;
27
+ // Set true on explicit disconnect() so scheduled retries don't resurrect the connection
28
+ this.explicitlyDisconnected = false;
29
+ // Last connect params — kept so reconnect can rebuild the URL without the caller
30
+ // re-supplying them. Cleared on disconnect().
31
+ this.lastParams = null;
32
+ // Reconnect attempt counter (resets on successful connect)
33
+ this.reconnectAttempt = 0;
34
+ this.reconnectTimer = null;
35
+ // Connection state as Angular signal — for UI indicators / route resolvers
36
+ this.connectionState = signal(WS_CONNECTION_STATE.DISCONNECTED);
37
+ // Inbound message stream — NotificationInboxService subscribes and routes per type
38
+ this.messages$ = new Subject();
39
+ }
40
+ // ----------- public API -----------
41
+ /**
42
+ * Establish the WebSocket connection.
43
+ *
44
+ * Idempotent — if already OPEN, resolves immediately.
45
+ * In-flight calls are de-duplicated.
46
+ * Any stale (non-OPEN) socket is torn down before rebuild.
47
+ */
48
+ async connect(params) {
49
+ this.explicitlyDisconnected = false;
50
+ this.lastParams = params;
51
+ if (this.connectionState() === WS_CONNECTION_STATE.CONNECTED) {
52
+ return;
53
+ }
54
+ if (this.connectingPromise) {
55
+ return this.connectingPromise;
56
+ }
57
+ if (this.socket) {
58
+ try {
59
+ this.socket.complete();
60
+ }
61
+ catch { /* ignore */ }
62
+ this.socket = null;
63
+ this.socketSub?.unsubscribe();
64
+ this.socketSub = null;
65
+ }
66
+ this.connectingPromise = this.doConnect(params);
67
+ try {
68
+ await this.connectingPromise;
69
+ }
70
+ finally {
71
+ this.connectingPromise = null;
72
+ }
73
+ }
74
+ async doConnect(params) {
75
+ const baseUrl = Common.notificationWebSocketUrl;
76
+ if (!baseUrl) {
77
+ this.connectionState.set(WS_CONNECTION_STATE.DISCONNECTED);
78
+ return;
79
+ }
80
+ if (!params.userId) {
81
+ console.warn('[NotificationWS] No userId provided — skipping connect');
82
+ this.connectionState.set(WS_CONNECTION_STATE.FAILED);
83
+ return;
84
+ }
85
+ // BE doc: ws://host/ws?userId=...&appId=...&tenantId=...
86
+ const url = `${baseUrl}?userId=${encodeURIComponent(params.userId)}` +
87
+ (params.appId ? `&appId=${encodeURIComponent(params.appId)}` : '') +
88
+ (params.tenantId ? `&tenantId=${encodeURIComponent(params.tenantId)}` : '');
89
+ this.connectionState.set(WS_CONNECTION_STATE.CONNECTING);
90
+ return new Promise((resolve) => {
91
+ this.socket = webSocket({
92
+ url,
93
+ openObserver: {
94
+ next: () => {
95
+ this.connectionState.set(WS_CONNECTION_STATE.CONNECTED);
96
+ this.reconnectAttempt = 0;
97
+ resolve();
98
+ },
99
+ },
100
+ closeObserver: {
101
+ next: () => {
102
+ if (this.connectionState() !== WS_CONNECTION_STATE.CLOSED) {
103
+ this.connectionState.set(WS_CONNECTION_STATE.DISCONNECTED);
104
+ }
105
+ this.scheduleReconnect();
106
+ resolve();
107
+ },
108
+ },
109
+ });
110
+ this.socketSub = this.socket.subscribe({
111
+ next: (msg) => this.handleIncoming(msg),
112
+ error: (err) => {
113
+ console.error('[NotificationWS] Socket error:', err);
114
+ this.connectionState.set(WS_CONNECTION_STATE.FAILED);
115
+ this.scheduleReconnect();
116
+ resolve();
117
+ },
118
+ });
119
+ });
120
+ }
121
+ /**
122
+ * Send a message over the socket. Silently no-ops if not connected.
123
+ */
124
+ send(message) {
125
+ if (!this.socket || this.connectionState() !== WS_CONNECTION_STATE.CONNECTED) {
126
+ return;
127
+ }
128
+ try {
129
+ this.socket.next(message);
130
+ }
131
+ catch (error) {
132
+ console.error('[NotificationWS] Failed to send message:', error);
133
+ }
134
+ }
135
+ /**
136
+ * Tear down the socket.
137
+ *
138
+ * Sets explicitlyDisconnected so any pending retry timers become no-ops,
139
+ * then closes the socket and clears state.
140
+ */
141
+ async disconnect() {
142
+ this.explicitlyDisconnected = true;
143
+ this.connectingPromise = null;
144
+ this.lastParams = null;
145
+ if (this.reconnectTimer) {
146
+ clearTimeout(this.reconnectTimer);
147
+ this.reconnectTimer = null;
148
+ }
149
+ if (this.socket) {
150
+ try {
151
+ this.socket.complete();
152
+ }
153
+ catch { /* ignore */ }
154
+ this.socket = null;
155
+ }
156
+ this.socketSub?.unsubscribe();
157
+ this.socketSub = null;
158
+ this.reconnectAttempt = 0;
159
+ this.connectionState.set(WS_CONNECTION_STATE.CLOSED);
160
+ }
161
+ // ----------- internal -----------
162
+ handleIncoming(message) {
163
+ if (!message || typeof message !== 'object')
164
+ return;
165
+ // Heartbeat: server pings every ~30s; we MUST reply or BE will close the socket.
166
+ if (message.type === WS_MESSAGE_TYPE.HEARTBEAT) {
167
+ this.send({ type: WS_MESSAGE_TYPE.HEARTBEAT });
168
+ return;
169
+ }
170
+ if (message.type === WS_MESSAGE_TYPE.CONNECTION_ESTABLISHED) {
171
+ this.connectionState.set(WS_CONNECTION_STATE.CONNECTED);
172
+ }
173
+ if (message.type === WS_MESSAGE_TYPE.ERROR) {
174
+ console.warn('[NotificationWS] Server error:', message.error);
175
+ }
176
+ this.messages$.next(message);
177
+ }
178
+ scheduleReconnect() {
179
+ if (this.explicitlyDisconnected)
180
+ return;
181
+ if (this.reconnectTimer)
182
+ return;
183
+ if (!this.lastParams)
184
+ return; // can't reconnect without params
185
+ const delays = NOTIFICATION_WS_CONFIG.RECONNECT_DELAYS_MS;
186
+ const delay = delays[Math.min(this.reconnectAttempt, delays.length - 1)];
187
+ this.reconnectAttempt++;
188
+ this.connectionState.set(WS_CONNECTION_STATE.RECONNECTING);
189
+ this.reconnectTimer = setTimeout(() => {
190
+ this.reconnectTimer = null;
191
+ if (!this.explicitlyDisconnected && this.lastParams) {
192
+ this.connect(this.lastParams);
193
+ }
194
+ }, delay);
195
+ }
196
+ /**
197
+ * Snapshot of current connection state — for debugging.
198
+ */
199
+ isConnected() {
200
+ return this.connectionState() === WS_CONNECTION_STATE.CONNECTED;
201
+ }
202
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: NotificationWebSocketService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
203
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: NotificationWebSocketService, providedIn: 'root' }); }
204
+ }
205
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: NotificationWebSocketService, decorators: [{
206
+ type: Injectable,
207
+ args: [{ providedIn: 'root' }]
208
+ }] });
209
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90aWZpY2F0aW9uLXdlYnNvY2tldC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9kYXRhLWFjY2Vzcy9zcmMvbGliL3RhYi1jb3JlLXV0aWxpdHkvY29yZS9zZXJ2aWNlL25vdGlmaWNhdGlvbi9ub3RpZmljYXRpb24td2Vic29ja2V0LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLE9BQU8sRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDN0MsT0FBTyxFQUFFLFNBQVMsRUFBb0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDdkQsT0FBTyxFQUNMLHNCQUFzQixFQUV0QixtQkFBbUIsRUFDbkIsZUFBZSxHQUVoQixNQUFNLGdEQUFnRCxDQUFDOztBQUV4RDs7Ozs7Ozs7Ozs7OztHQWFHO0FBRUgsTUFBTSxPQUFPLDRCQUE0QjtJQUR6QztRQUVVLFdBQU0sR0FBaUMsSUFBSSxDQUFDO1FBQzVDLGNBQVMsR0FBd0IsSUFBSSxDQUFDO1FBRTlDLHdFQUF3RTtRQUNoRSxzQkFBaUIsR0FBeUIsSUFBSSxDQUFDO1FBRXZELHdGQUF3RjtRQUNoRiwyQkFBc0IsR0FBRyxLQUFLLENBQUM7UUFFdkMsaUZBQWlGO1FBQ2pGLDhDQUE4QztRQUN0QyxlQUFVLEdBQThDLElBQUksQ0FBQztRQUVyRSwyREFBMkQ7UUFDbkQscUJBQWdCLEdBQUcsQ0FBQyxDQUFDO1FBQ3JCLG1CQUFjLEdBQXlDLElBQUksQ0FBQztRQUVwRSwyRUFBMkU7UUFDbEUsb0JBQWUsR0FBRyxNQUFNLENBQW9CLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRXZGLG1GQUFtRjtRQUMxRSxjQUFTLEdBQUcsSUFBSSxP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QUNwRCxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNoQyxDQUFDO1FBQ0gsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ1osQ0FBQztJQUVEOztPQUVHO0lBQ0gsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDLGVBQWUsRUFBRSxLQUFLLG1CQUFtQixDQUFDLFNBQVMsQ0FBQztJQUNsRSxDQUFDOytHQXpNVSw0QkFBNEI7bUhBQTVCLDRCQUE0QixjQURmLE1BQU07OzRGQUNuQiw0QkFBNEI7a0JBRHhDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyB3ZWJTb2NrZXQsIFdlYlNvY2tldFN1YmplY3QgfSBmcm9tICdyeGpzL3dlYlNvY2tldCc7XHJcbmltcG9ydCB7IENvbW1vbiB9IGZyb20gJy4uLy4uLy4uL2FwcC9jb25zdGFudHMvY29tbW9uJztcclxuaW1wb3J0IHtcclxuICBOT1RJRklDQVRJT05fV1NfQ09ORklHLFxyXG4gIE5vdGlmaWNhdGlvbldlYlNvY2tldENvbm5lY3RQYXJhbXMsXHJcbiAgV1NfQ09OTkVDVElPTl9TVEFURSxcclxuICBXU19NRVNTQUdFX1RZUEUsXHJcbiAgV3NDb25uZWN0aW9uU3RhdGUsXHJcbn0gZnJvbSAnLi4vLi4vLi4vYXBwL2ludGVyZmFjZXMvbm90aWZpY2F0aW9uLmludGVyZmFjZSc7XHJcblxyXG4vKipcclxuICogTG93LWxldmVsIE5vdGlmaWNhdGlvbiBXZWJTb2NrZXQgdHJhbnNwb3J0LlxyXG4gKlxyXG4gKiBQdXJlIOKAlCBubyBzdG9yYWdlIC8gYXV0aCBjb3VwbGluZy4gVGhlIGNhbGxlciAoU0RLIGZhY2FkZSBvciBhcHAgbGF5ZXIpXHJcbiAqIHN1cHBsaWVzIGFsbCBhdXRoIGlkZW50aWZpZXJzIHZpYSBgY29ubmVjdChwYXJhbXMpYC5cclxuICpcclxuICogTWlycm9ycyB0aGUgU2lnbmFsUiBpbmZyYXN0cnVjdHVyZSBwYXR0ZXJuOlxyXG4gKiAgLSBjb25uZWN0KCkgaXMgaWRlbXBvdGVudCwgZGVkdXBlcyBjb25jdXJyZW50IGNhbGxzLCB0ZWFycyBkb3duIHN0YWxlIHNvY2tldHNcclxuICogIC0gZGlzY29ubmVjdCgpIGZsaXBzIGFuIGV4cGxpY2l0LWRpc2Nvbm5lY3RlZCBmbGFnIHNvIHJldHJpZXMgZG9uJ3QgcmV2aXZlXHJcbiAqICAtIHN0YXRlIGV4cG9zZWQgYXMgQW5ndWxhciBzaWduYWxcclxuICogIC0gaW5ib3VuZCBtZXNzYWdlcyBmb3J3YXJkZWQgb24gYG1lc3NhZ2VzJGAgZm9yIGhpZ2hlci1sZXZlbCBzZXJ2aWNlIHRvIHJvdXRlXHJcbiAqXHJcbiAqIEludGVybmFsIHVzZSDigJQgY29uc3VtZXJzIHNob3VsZCB1c2UgYE5vdGlmaWNhdGlvbkluYm94U2VydmljZWAgaW5zdGVhZC5cclxuICovXHJcbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXHJcbmV4cG9ydCBjbGFzcyBOb3RpZmljYXRpb25XZWJTb2NrZXRTZXJ2aWNlIHtcclxuICBwcml2YXRlIHNvY2tldDogV2ViU29ja2V0U3ViamVjdDxhbnk+IHwgbnVsbCA9IG51bGw7XHJcbiAgcHJpdmF0ZSBzb2NrZXRTdWI6IFN1YnNjcmlwdGlvbiB8IG51bGwgPSBudWxsO1xyXG5cclxuICAvLyBJbi1mbGlnaHQgY29ubmVjdCBwcm9taXNlIOKAlCB1c2VkIHRvIGRlZHVwZSBjb25jdXJyZW50IGNvbm5lY3QoKSBjYWxsc1xyXG4gIHByaXZhdGUgY29ubmVjdGluZ1Byb21pc2U6IFByb21pc2U8dm9pZD4gfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLy8gU2V0IHRydWUgb24gZXhwbGljaXQgZGlzY29ubmVjdCgpIHNvIHNjaGVkdWxlZCByZXRyaWVzIGRvbid0IHJlc3VycmVjdCB0aGUgY29ubmVjdGlvblxyXG4gIHByaXZhdGUgZXhwbGljaXRseURpc2Nvbm5lY3RlZCA9IGZhbHNlO1xyXG5cclxuICAvLyBMYXN0IGNvbm5lY3QgcGFyYW1zIOKAlCBrZXB0IHNvIHJlY29ubmVjdCBjYW4gcmVidWlsZCB0aGUgVVJMIHdpdGhvdXQgdGhlIGNhbGxlclxyXG4gIC8vIHJlLXN1cHBseWluZyB0aGVtLiBDbGVhcmVkIG9uIGRpc2Nvbm5lY3QoKS5cclxuICBwcml2YXRlIGxhc3RQYXJhbXM6IE5vdGlmaWNhdGlvbldlYlNvY2tldENvbm5lY3RQYXJhbXMgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLy8gUmVjb25uZWN0IGF0dGVtcHQgY291bnRlciAocmVzZXRzIG9uIHN1Y2Nlc3NmdWwgY29ubmVjdClcclxuICBwcml2YXRlIHJlY29ubmVjdEF0dGVtcHQgPSAwO1xyXG4gIHByaXZhdGUgcmVjb25uZWN0VGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIC8vIENvbm5lY3Rpb24gc3RhdGUgYXMgQW5ndWxhciBzaWduYWwg4oCUIGZvciBVSSBpbmRpY2F0b3JzIC8gcm91dGUgcmVzb2x2ZXJzXHJcbiAgcmVhZG9ubHkgY29ubmVjdGlvblN0YXRlID0gc2lnbmFsPFdzQ29ubmVjdGlvblN0YXRlPihXU19DT05ORUNUSU9OX1NUQVRFLkRJU0NPTk5FQ1RFRCk7XHJcblxyXG4gIC8vIEluYm91bmQgbWVzc2FnZSBzdHJlYW0g4oCUIE5vdGlmaWNhdGlvbkluYm94U2VydmljZSBzdWJzY3JpYmVzIGFuZCByb3V0ZXMgcGVyIHR5cGVcclxuICByZWFkb25seSBtZXNzYWdlcyQgPSBuZXcgU3ViamVjdDxhbnk+KCk7XHJcblxyXG4gIC8vIC0tLS0tLS0tLS0tIHB1YmxpYyBBUEkgLS0tLS0tLS0tLS1cclxuXHJcbiAgLyoqXHJcbiAgICogRXN0YWJsaXNoIHRoZSBXZWJTb2NrZXQgY29ubmVjdGlvbi5cclxuICAgKlxyXG4gICAqIElkZW1wb3RlbnQg4oCUIGlmIGFscmVhZHkgT1BFTiwgcmVzb2x2ZXMgaW1tZWRpYXRlbHkuXHJcbiAgICogSW4tZmxpZ2h0IGNhbGxzIGFyZSBkZS1kdXBsaWNhdGVkLlxyXG4gICAqIEFueSBzdGFsZSAobm9uLU9QRU4pIHNvY2tldCBpcyB0b3JuIGRvd24gYmVmb3JlIHJlYnVpbGQuXHJcbiAgICovXHJcbiAgYXN5bmMgY29ubmVjdChwYXJhbXM6IE5vdGlmaWNhdGlvbldlYlNvY2tldENvbm5lY3RQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHRoaXMuZXhwbGljaXRseURpc2Nvbm5lY3RlZCA9IGZhbHNlO1xyXG4gICAgdGhpcy5sYXN0UGFyYW1zID0gcGFyYW1zO1xyXG5cclxuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25TdGF0ZSgpID09PSBXU19DT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuY29ubmVjdGluZ1Byb21pc2UpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGluZ1Byb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuc29ja2V0KSB7XHJcbiAgICAgIHRyeSB7IHRoaXMuc29ja2V0LmNvbXBsZXRlKCk7IH0gY2F0Y2ggeyAvKiBpZ25vcmUgKi8gfVxyXG4gICAgICB0aGlzLnNvY2tldCA9IG51bGw7XHJcbiAgICAgIHRoaXMuc29ja2V0U3ViPy51bnN1YnNjcmliZSgpO1xyXG4gICAgICB0aGlzLnNvY2tldFN1YiA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5jb25uZWN0aW5nUHJvbWlzZSA9IHRoaXMuZG9Db25uZWN0KHBhcmFtcyk7XHJcbiAgICB0cnkge1xyXG4gICAgICBhd2FpdCB0aGlzLmNvbm5lY3RpbmdQcm9taXNlO1xyXG4gICAgfSBmaW5hbGx5IHtcclxuICAgICAgdGhpcy5jb25uZWN0aW5nUHJvbWlzZSA9IG51bGw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGRvQ29ubmVjdChwYXJhbXM6IE5vdGlmaWNhdGlvbldlYlNvY2tldENvbm5lY3RQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGJhc2VVcmwgPSBDb21tb24ubm90aWZpY2F0aW9uV2ViU29ja2V0VXJsO1xyXG4gICAgaWYgKCFiYXNlVXJsKSB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChXU19DT05ORUNUSU9OX1NUQVRFLkRJU0NPTk5FQ1RFRCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXBhcmFtcy51c2VySWQpIHtcclxuICAgICAgY29uc29sZS53YXJuKCdbTm90aWZpY2F0aW9uV1NdIE5vIHVzZXJJZCBwcm92aWRlZCDigJQgc2tpcHBpbmcgY29ubmVjdCcpO1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5GQUlMRUQpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQkUgZG9jOiB3czovL2hvc3Qvd3M/dXNlcklkPS4uLiZhcHBJZD0uLi4mdGVuYW50SWQ9Li4uXHJcbiAgICBjb25zdCB1cmwgPSBgJHtiYXNlVXJsfT91c2VySWQ9JHtlbmNvZGVVUklDb21wb25lbnQocGFyYW1zLnVzZXJJZCl9YCArXHJcbiAgICAgIChwYXJhbXMuYXBwSWQgPyBgJmFwcElkPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHBhcmFtcy5hcHBJZCl9YCA6ICcnKSArXHJcbiAgICAgIChwYXJhbXMudGVuYW50SWQgPyBgJnRlbmFudElkPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHBhcmFtcy50ZW5hbnRJZCl9YCA6ICcnKTtcclxuXHJcbiAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5DT05ORUNUSU5HKTtcclxuXHJcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcclxuICAgICAgdGhpcy5zb2NrZXQgPSB3ZWJTb2NrZXQ8YW55Pih7XHJcbiAgICAgICAgdXJsLFxyXG4gICAgICAgIG9wZW5PYnNlcnZlcjoge1xyXG4gICAgICAgICAgbmV4dDogKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5DT05ORUNURUQpO1xyXG4gICAgICAgICAgICB0aGlzLnJlY29ubmVjdEF0dGVtcHQgPSAwO1xyXG4gICAgICAgICAgICByZXNvbHZlKCk7XHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgY2xvc2VPYnNlcnZlcjoge1xyXG4gICAgICAgICAgbmV4dDogKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uU3RhdGUoKSAhPT0gV1NfQ09OTkVDVElPTl9TVEFURS5DTE9TRUQpIHtcclxuICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5ESVNDT05ORUNURUQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuc2NoZWR1bGVSZWNvbm5lY3QoKTtcclxuICAgICAgICAgICAgcmVzb2x2ZSgpO1xyXG4gICAgICAgICAgfSxcclxuICAgICAgICB9LFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHRoaXMuc29ja2V0U3ViID0gdGhpcy5zb2NrZXQuc3Vic2NyaWJlKHtcclxuICAgICAgICBuZXh0OiAobXNnKSA9PiB0aGlzLmhhbmRsZUluY29taW5nKG1zZyksXHJcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcclxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tOb3RpZmljYXRpb25XU10gU29ja2V0IGVycm9yOicsIGVycik7XHJcbiAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5GQUlMRUQpO1xyXG4gICAgICAgICAgdGhpcy5zY2hlZHVsZVJlY29ubmVjdCgpO1xyXG4gICAgICAgICAgcmVzb2x2ZSgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZW5kIGEgbWVzc2FnZSBvdmVyIHRoZSBzb2NrZXQuIFNpbGVudGx5IG5vLW9wcyBpZiBub3QgY29ubmVjdGVkLlxyXG4gICAqL1xyXG4gIHNlbmQobWVzc2FnZTogUmVjb3JkPHN0cmluZywgYW55Pik6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLnNvY2tldCB8fCB0aGlzLmNvbm5lY3Rpb25TdGF0ZSgpICE9PSBXU19DT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLnNvY2tldC5uZXh0KG1lc3NhZ2UpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignW05vdGlmaWNhdGlvbldTXSBGYWlsZWQgdG8gc2VuZCBtZXNzYWdlOicsIGVycm9yKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRlYXIgZG93biB0aGUgc29ja2V0LlxyXG4gICAqXHJcbiAgICogU2V0cyBleHBsaWNpdGx5RGlzY29ubmVjdGVkIHNvIGFueSBwZW5kaW5nIHJldHJ5IHRpbWVycyBiZWNvbWUgbm8tb3BzLFxyXG4gICAqIHRoZW4gY2xvc2VzIHRoZSBzb2NrZXQgYW5kIGNsZWFycyBzdGF0ZS5cclxuICAgKi9cclxuICBhc3luYyBkaXNjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgdGhpcy5leHBsaWNpdGx5RGlzY29ubmVjdGVkID0gdHJ1ZTtcclxuICAgIHRoaXMuY29ubmVjdGluZ1Byb21pc2UgPSBudWxsO1xyXG4gICAgdGhpcy5sYXN0UGFyYW1zID0gbnVsbDtcclxuXHJcbiAgICBpZiAodGhpcy5yZWNvbm5lY3RUaW1lcikge1xyXG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5yZWNvbm5lY3RUaW1lcik7XHJcbiAgICAgIHRoaXMucmVjb25uZWN0VGltZXIgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLnNvY2tldCkge1xyXG4gICAgICB0cnkgeyB0aGlzLnNvY2tldC5jb21wbGV0ZSgpOyB9IGNhdGNoIHsgLyogaWdub3JlICovIH1cclxuICAgICAgdGhpcy5zb2NrZXQgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuc29ja2V0U3ViPy51bnN1YnNjcmliZSgpO1xyXG4gICAgdGhpcy5zb2NrZXRTdWIgPSBudWxsO1xyXG5cclxuICAgIHRoaXMucmVjb25uZWN0QXR0ZW1wdCA9IDA7XHJcbiAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5DTE9TRUQpO1xyXG4gIH1cclxuXHJcbiAgLy8gLS0tLS0tLS0tLS0gaW50ZXJuYWwgLS0tLS0tLS0tLS1cclxuXHJcbiAgcHJpdmF0ZSBoYW5kbGVJbmNvbWluZyhtZXNzYWdlOiBhbnkpOiB2b2lkIHtcclxuICAgIGlmICghbWVzc2FnZSB8fCB0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcpIHJldHVybjtcclxuXHJcbiAgICAvLyBIZWFydGJlYXQ6IHNlcnZlciBwaW5ncyBldmVyeSB+MzBzOyB3ZSBNVVNUIHJlcGx5IG9yIEJFIHdpbGwgY2xvc2UgdGhlIHNvY2tldC5cclxuICAgIGlmIChtZXNzYWdlLnR5cGUgPT09IFdTX01FU1NBR0VfVFlQRS5IRUFSVEJFQVQpIHtcclxuICAgICAgdGhpcy5zZW5kKHsgdHlwZTogV1NfTUVTU0FHRV9UWVBFLkhFQVJUQkVBVCB9KTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChtZXNzYWdlLnR5cGUgPT09IFdTX01FU1NBR0VfVFlQRS5DT05ORUNUSU9OX0VTVEFCTElTSEVEKSB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChXU19DT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG1lc3NhZ2UudHlwZSA9PT0gV1NfTUVTU0FHRV9UWVBFLkVSUk9SKSB7XHJcbiAgICAgIGNvbnNvbGUud2FybignW05vdGlmaWNhdGlvbldTXSBTZXJ2ZXIgZXJyb3I6JywgbWVzc2FnZS5lcnJvcik7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5tZXNzYWdlcyQubmV4dChtZXNzYWdlKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2NoZWR1bGVSZWNvbm5lY3QoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5leHBsaWNpdGx5RGlzY29ubmVjdGVkKSByZXR1cm47XHJcbiAgICBpZiAodGhpcy5yZWNvbm5lY3RUaW1lcikgcmV0dXJuO1xyXG4gICAgaWYgKCF0aGlzLmxhc3RQYXJhbXMpIHJldHVybjsgLy8gY2FuJ3QgcmVjb25uZWN0IHdpdGhvdXQgcGFyYW1zXHJcblxyXG4gICAgY29uc3QgZGVsYXlzID0gTk9USUZJQ0FUSU9OX1dTX0NPTkZJRy5SRUNPTk5FQ1RfREVMQVlTX01TO1xyXG4gICAgY29uc3QgZGVsYXkgPSBkZWxheXNbTWF0aC5taW4odGhpcy5yZWNvbm5lY3RBdHRlbXB0LCBkZWxheXMubGVuZ3RoIC0gMSldO1xyXG4gICAgdGhpcy5yZWNvbm5lY3RBdHRlbXB0Kys7XHJcblxyXG4gICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KFdTX0NPTk5FQ1RJT05fU1RBVEUuUkVDT05ORUNUSU5HKTtcclxuXHJcbiAgICB0aGlzLnJlY29ubmVjdFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIHRoaXMucmVjb25uZWN0VGltZXIgPSBudWxsO1xyXG4gICAgICBpZiAoIXRoaXMuZXhwbGljaXRseURpc2Nvbm5lY3RlZCAmJiB0aGlzLmxhc3RQYXJhbXMpIHtcclxuICAgICAgICB0aGlzLmNvbm5lY3QodGhpcy5sYXN0UGFyYW1zKTtcclxuICAgICAgfVxyXG4gICAgfSwgZGVsYXkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU25hcHNob3Qgb2YgY3VycmVudCBjb25uZWN0aW9uIHN0YXRlIOKAlCBmb3IgZGVidWdnaW5nLlxyXG4gICAqL1xyXG4gIGlzQ29ubmVjdGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvblN0YXRlKCkgPT09IFdTX0NPTk5FQ1RJT05fU1RBVEUuQ09OTkVDVEVEO1xyXG4gIH1cclxufVxyXG4iXX0=