@techextensor/tab-core-utility 2.2.181 → 2.2.184

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 (73) hide show
  1. package/esm2022/index.mjs +5 -1
  2. package/esm2022/lib/tab-core-utility/app/constants/api-constants.mjs +24 -13
  3. package/esm2022/lib/tab-core-utility/app/constants/common.mjs +14 -50
  4. package/esm2022/lib/tab-core-utility/app/constants/storage-constants.mjs +2 -2
  5. package/esm2022/lib/tab-core-utility/app/crud/tab-crud.service.mjs +38 -49
  6. package/esm2022/lib/tab-core-utility/app/crud/tab-delete.service.mjs +81 -30
  7. package/esm2022/lib/tab-core-utility/app/crud/tab-formio.service.mjs +141 -12
  8. package/esm2022/lib/tab-core-utility/app/crud/tab-get.service.mjs +136 -35
  9. package/esm2022/lib/tab-core-utility/app/crud/tab-insert.service.mjs +89 -38
  10. package/esm2022/lib/tab-core-utility/app/crud/tab-update.service.mjs +152 -131
  11. package/esm2022/lib/tab-core-utility/app/enums/query.enum.mjs +7 -7
  12. package/esm2022/lib/tab-core-utility/app/helpers/common/app.helpers.mjs +6 -17
  13. package/esm2022/lib/tab-core-utility/app/helpers/common/dsq.helpers.mjs +9 -11
  14. package/esm2022/lib/tab-core-utility/app/helpers/common/meta-data.helpers.mjs +13 -13
  15. package/esm2022/lib/tab-core-utility/app/helpers/common/req-res.helpers.mjs +7 -45
  16. package/esm2022/lib/tab-core-utility/app/helpers/common/where-clause.helpers.mjs +79 -76
  17. package/esm2022/lib/tab-core-utility/app/helpers/response.adapter.mjs +38 -0
  18. package/esm2022/lib/tab-core-utility/app/helpers/screen/grid.helpers.mjs +8 -4
  19. package/esm2022/lib/tab-core-utility/app/helpers/screen/screen.helpers.mjs +8 -33
  20. package/esm2022/lib/tab-core-utility/app/interfaces/common.interface.mjs +1 -1
  21. package/esm2022/lib/tab-core-utility/app/interfaces/signalr.interface.mjs +42 -0
  22. package/esm2022/lib/tab-core-utility/app/models/api-query.class.mjs +39 -1
  23. package/esm2022/lib/tab-core-utility/app/models/app-field.model.mjs +36 -7
  24. package/esm2022/lib/tab-core-utility/app/models/app-object.model.mjs +84 -47
  25. package/esm2022/lib/tab-core-utility/app/models/app-screen.model.mjs +24 -13
  26. package/esm2022/lib/tab-core-utility/app/models/data-source-query.model.mjs +57 -23
  27. package/esm2022/lib/tab-core-utility/app/models/filter.model.mjs +21 -10
  28. package/esm2022/lib/tab-core-utility/app/models/parameter.model.mjs +12 -6
  29. package/esm2022/lib/tab-core-utility/app/models/sort.model.mjs +11 -4
  30. package/esm2022/lib/tab-core-utility/app/utils/json.util.mjs +17 -16
  31. package/esm2022/lib/tab-core-utility/app/utils/req-res.util.mjs +1 -55
  32. package/esm2022/lib/tab-core-utility/app/utils/tab-app.util.mjs +1 -164
  33. package/esm2022/lib/tab-core-utility/core/http-client/api.service.mjs +63 -1
  34. package/esm2022/lib/tab-core-utility/core/service/signalr/operation-tracker.service.mjs +82 -0
  35. package/esm2022/lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service.mjs +252 -0
  36. package/esm2022/lib/tab-core-utility/core/service/signalr/signalr.service.mjs +207 -0
  37. package/index.d.ts +4 -0
  38. package/lib/tab-core-utility/app/constants/api-constants.d.ts +13 -10
  39. package/lib/tab-core-utility/app/constants/common.d.ts +9 -0
  40. package/lib/tab-core-utility/app/constants/storage-constants.d.ts +1 -1
  41. package/lib/tab-core-utility/app/crud/tab-crud.service.d.ts +8 -1
  42. package/lib/tab-core-utility/app/crud/tab-delete.service.d.ts +20 -10
  43. package/lib/tab-core-utility/app/crud/tab-formio.service.d.ts +33 -6
  44. package/lib/tab-core-utility/app/crud/tab-get.service.d.ts +45 -3
  45. package/lib/tab-core-utility/app/crud/tab-insert.service.d.ts +16 -21
  46. package/lib/tab-core-utility/app/crud/tab-update.service.d.ts +34 -19
  47. package/lib/tab-core-utility/app/enums/query.enum.d.ts +3 -6
  48. package/lib/tab-core-utility/app/helpers/common/app.helpers.d.ts +3 -8
  49. package/lib/tab-core-utility/app/helpers/common/dsq.helpers.d.ts +3 -0
  50. package/lib/tab-core-utility/app/helpers/common/meta-data.helpers.d.ts +3 -3
  51. package/lib/tab-core-utility/app/helpers/common/req-res.helpers.d.ts +7 -51
  52. package/lib/tab-core-utility/app/helpers/common/where-clause.helpers.d.ts +1 -0
  53. package/lib/tab-core-utility/app/helpers/response.adapter.d.ts +22 -0
  54. package/lib/tab-core-utility/app/helpers/screen/grid.helpers.d.ts +2 -1
  55. package/lib/tab-core-utility/app/helpers/screen/screen.helpers.d.ts +1 -0
  56. package/lib/tab-core-utility/app/interfaces/common.interface.d.ts +50 -2
  57. package/lib/tab-core-utility/app/interfaces/signalr.interface.d.ts +80 -0
  58. package/lib/tab-core-utility/app/models/api-query.class.d.ts +54 -9
  59. package/lib/tab-core-utility/app/models/app-field.model.d.ts +4 -2
  60. package/lib/tab-core-utility/app/models/app-object.model.d.ts +5 -3
  61. package/lib/tab-core-utility/app/models/app-screen.model.d.ts +2 -2
  62. package/lib/tab-core-utility/app/models/data-source-query.model.d.ts +7 -2
  63. package/lib/tab-core-utility/app/models/filter.model.d.ts +2 -2
  64. package/lib/tab-core-utility/app/models/parameter.model.d.ts +2 -2
  65. package/lib/tab-core-utility/app/models/sort.model.d.ts +1 -1
  66. package/lib/tab-core-utility/app/utils/json.util.d.ts +3 -2
  67. package/lib/tab-core-utility/app/utils/req-res.util.d.ts +1 -9
  68. package/lib/tab-core-utility/app/utils/tab-app.util.d.ts +0 -61
  69. package/lib/tab-core-utility/core/http-client/api.service.d.ts +37 -0
  70. package/lib/tab-core-utility/core/service/signalr/operation-tracker.service.d.ts +40 -0
  71. package/lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service.d.ts +68 -0
  72. package/lib/tab-core-utility/core/service/signalr/signalr.service.d.ts +122 -0
  73. package/package.json +3 -2
@@ -0,0 +1,252 @@
1
+ import { inject, Injectable, signal } from '@angular/core';
2
+ import * as signalR from '@microsoft/signalr';
3
+ import { Subject } from 'rxjs';
4
+ import { Common } from '../../../app/constants/common';
5
+ import { SIGNALR_HUB_METHODS, SIGNALR_EVENTS, CRUD_OPERATION, CONNECTION_STATE, } from '../../../app/interfaces/signalr.interface';
6
+ import { StorageConstants } from '../../../app/constants/storage-constants';
7
+ import { SessionStorageService } from '../../../auth/session-storage.service';
8
+ import { LocalStorageService } from '../../../auth/local-storage.service';
9
+ import * as i0 from "@angular/core";
10
+ /**
11
+ * SignalR Infrastructure Service
12
+ * Handles low-level WebSocket connection, group management, and reconnection
13
+ * Internal use only - components should use SignalRService instead
14
+ */
15
+ export class SignalRInfrastructure {
16
+ constructor() {
17
+ this.hubConnection = null;
18
+ // Session storage
19
+ this.sessionStorageService = inject(SessionStorageService);
20
+ // local storage
21
+ this.localStorageService = inject(LocalStorageService);
22
+ // Connection state as signal
23
+ this.connectionState = signal(CONNECTION_STATE.DISCONNECTED);
24
+ // Notification stream (internal - emits to SignalRService)
25
+ this.notifications$ = new Subject();
26
+ // Track active groups to rejoin after reconnection
27
+ this.activeGroups = new Set();
28
+ }
29
+ /**
30
+ * Helper method to get value from storage
31
+ * @param type The type of storage, 'Session' or 'Local'
32
+ * @param key The key to retrieve the value for
33
+ * @returns The value from storage, or null if not available
34
+ */
35
+ getFromStorage(type, key) {
36
+ try {
37
+ let info = null;
38
+ if (type === 'Session') {
39
+ // Get value from session storage
40
+ info = this.sessionStorageService.getSessionStorage(key);
41
+ }
42
+ if (type === 'Local') {
43
+ // Get value from local storage
44
+ info = this.localStorageService.getLocalStorage(key);
45
+ }
46
+ if (info && typeof info === 'string') {
47
+ // Parse the value if it's a string
48
+ info = JSON.parse(info);
49
+ }
50
+ return info;
51
+ }
52
+ catch (error) {
53
+ // Log error if failed to get value from storage
54
+ console.warn('Failed to get current app ID from session:', error);
55
+ return null;
56
+ }
57
+ }
58
+ get appId() {
59
+ const appInfo = this.getFromStorage('Session', StorageConstants.appInfo);
60
+ return appInfo?.Id || null;
61
+ }
62
+ get environmentId() {
63
+ const envInfo = this.getFromStorage('Session', StorageConstants.environmentInfo);
64
+ return envInfo?.Id || null;
65
+ }
66
+ get tenantId() {
67
+ const tenantInfo = this.getFromStorage('Local', StorageConstants.orgInfo);
68
+ return tenantInfo?.Id || null;
69
+ }
70
+ get token() {
71
+ const authInfo = this.getFromStorage('Local', StorageConstants.tokenInfo);
72
+ return authInfo?.token || null;
73
+ }
74
+ /**
75
+ * Connect to SignalR hub
76
+ */
77
+ async connect() {
78
+ if (this.hubConnection?.state === signalR.HubConnectionState.Connected) {
79
+ return;
80
+ }
81
+ // Get hub URL from Common (set during app initialization via Common.init())
82
+ const hubUrl = Common.signalRHubUrl;
83
+ if (!hubUrl) {
84
+ console.error('[SignalR] Hub URL not configured. Make sure Common.init() is called with environment.');
85
+ return;
86
+ }
87
+ try {
88
+ this.connectionState.set(CONNECTION_STATE.CONNECTING);
89
+ this.hubConnection = new signalR.HubConnectionBuilder()
90
+ .withUrl(hubUrl, {
91
+ accessTokenFactory: () => this.token || '',
92
+ skipNegotiation: false,
93
+ transport: signalR.HttpTransportType.WebSockets | signalR.HttpTransportType.ServerSentEvents,
94
+ })
95
+ .withAutomaticReconnect({
96
+ nextRetryDelayInMilliseconds: (retryContext) => {
97
+ // Exponential backoff: 0s, 2s, 10s, 30s, max 60s
98
+ if (retryContext.elapsedMilliseconds < 60000) {
99
+ return Math.min(1000 * Math.pow(2, retryContext.previousRetryCount), 60000);
100
+ }
101
+ return null; // Stop retrying after 1 minute
102
+ },
103
+ })
104
+ .configureLogging(signalR.LogLevel.Information)
105
+ .build();
106
+ this.registerEventHandlers();
107
+ this.registerConnectionLifecycle();
108
+ await this.hubConnection.start();
109
+ this.connectionState.set(CONNECTION_STATE.CONNECTED);
110
+ }
111
+ catch (error) {
112
+ this.connectionState.set(CONNECTION_STATE.FAILED);
113
+ // Retry after 1 minute
114
+ setTimeout(() => this.connect(), 60 * 1000);
115
+ }
116
+ }
117
+ /**
118
+ * Register SignalR event handlers for CRUD notifications
119
+ */
120
+ registerEventHandlers() {
121
+ if (!this.hubConnection)
122
+ return;
123
+ // INSERT notifications
124
+ this.hubConnection.on(SIGNALR_EVENTS.INSERT_COMPLETED, (notification) => {
125
+ const enriched = { ...notification, operation: CRUD_OPERATION.INSERT, receivedAt: new Date() };
126
+ this.notifications$.next(enriched);
127
+ });
128
+ // UPDATE notifications
129
+ this.hubConnection.on(SIGNALR_EVENTS.UPDATE_COMPLETED, (notification) => {
130
+ const enriched = { ...notification, operation: CRUD_OPERATION.UPDATE, receivedAt: new Date() };
131
+ this.notifications$.next(enriched);
132
+ });
133
+ // DELETE notifications
134
+ this.hubConnection.on(SIGNALR_EVENTS.DELETE_COMPLETED, (notification) => {
135
+ const enriched = { ...notification, operation: CRUD_OPERATION.DELETE, receivedAt: new Date() };
136
+ this.notifications$.next(enriched);
137
+ });
138
+ }
139
+ /**
140
+ * Register connection lifecycle handlers
141
+ */
142
+ registerConnectionLifecycle() {
143
+ if (!this.hubConnection)
144
+ return;
145
+ this.hubConnection.onreconnecting(() => {
146
+ this.connectionState.set(CONNECTION_STATE.RECONNECTING);
147
+ });
148
+ this.hubConnection.onreconnected(() => {
149
+ this.connectionState.set(CONNECTION_STATE.CONNECTED);
150
+ // Rejoin all groups after reconnection
151
+ this.rejoinGroups();
152
+ });
153
+ this.hubConnection.onclose(() => {
154
+ this.connectionState.set(CONNECTION_STATE.DISCONNECTED);
155
+ // Try to reconnect
156
+ setTimeout(() => this.connect(), 60 * 1000);
157
+ });
158
+ }
159
+ /**
160
+ * Join SignalR group for an AppObject
161
+ */
162
+ async joinGroup(appObjectId) {
163
+ if (!this.hubConnection || this.hubConnection.state !== signalR.HubConnectionState.Connected) {
164
+ return;
165
+ }
166
+ try {
167
+ if (!this.tenantId || !this.appId || !this.environmentId || !appObjectId) {
168
+ return;
169
+ }
170
+ await this.hubConnection.invoke(SIGNALR_HUB_METHODS.JOIN_GROUP, this.tenantId, this.appId, this.environmentId, appObjectId);
171
+ // Track this group for reconnection
172
+ this.activeGroups.add(appObjectId);
173
+ }
174
+ catch (error) {
175
+ console.error(`[SignalR] Failed to join group: ${appObjectId}`, error);
176
+ }
177
+ }
178
+ /**
179
+ * Leave SignalR group
180
+ */
181
+ async leaveGroup(appObjectId) {
182
+ if (!this.hubConnection || this.hubConnection.state !== signalR.HubConnectionState.Connected) {
183
+ // Remove from tracking even if not connected
184
+ this.activeGroups.delete(appObjectId);
185
+ return;
186
+ }
187
+ if (!this.tenantId || !this.appId || !this.environmentId || !appObjectId) {
188
+ return;
189
+ }
190
+ try {
191
+ await this.hubConnection.invoke(SIGNALR_HUB_METHODS.LEAVE_GROUP, this.tenantId, this.appId, this.environmentId, appObjectId);
192
+ // Remove from tracking
193
+ this.activeGroups.delete(appObjectId);
194
+ }
195
+ catch (error) {
196
+ console.error(`[SignalR] Failed to leave group: ${appObjectId}`, error);
197
+ }
198
+ }
199
+ /**
200
+ * Rejoin all active groups after reconnection
201
+ * This ensures components continue receiving notifications after network interruption
202
+ */
203
+ async rejoinGroups() {
204
+ if (this.activeGroups.size === 0) {
205
+ return;
206
+ }
207
+ // Get list of groups to rejoin
208
+ const groups = Array.from(this.activeGroups);
209
+ // Clear the set (will be re-added during joinGroup)
210
+ this.activeGroups.clear();
211
+ // Rejoin each group
212
+ for (const appObjectId of groups) {
213
+ await this.joinGroup(appObjectId);
214
+ }
215
+ }
216
+ /**
217
+ * Check if connected
218
+ */
219
+ isConnected() {
220
+ return this.hubConnection?.state === signalR.HubConnectionState.Connected;
221
+ }
222
+ /**
223
+ * Disconnect from SignalR hub (cleanup)
224
+ */
225
+ async disconnect() {
226
+ if (this.hubConnection) {
227
+ try {
228
+ await this.hubConnection.stop();
229
+ this.hubConnection = null;
230
+ this.connectionState.set(CONNECTION_STATE.DISCONNECTED);
231
+ }
232
+ catch (error) {
233
+ console.error('[SignalR] Error during disconnect:', error);
234
+ }
235
+ }
236
+ }
237
+ /**
238
+ * Get active groups (for debugging)
239
+ */
240
+ getActiveGroups() {
241
+ return Array.from(this.activeGroups);
242
+ }
243
+ static { this.ɵfac = function SignalRInfrastructure_Factory(t) { return new (t || SignalRInfrastructure)(); }; }
244
+ static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: SignalRInfrastructure, factory: SignalRInfrastructure.ɵfac, providedIn: 'root' }); }
245
+ }
246
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SignalRInfrastructure, [{
247
+ type: Injectable,
248
+ args: [{
249
+ providedIn: 'root',
250
+ }]
251
+ }], null, null); })();
252
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9kYXRhLWFjY2Vzcy9zcmMvbGliL3RhYi1jb3JlLXV0aWxpdHkvY29yZS9zZXJ2aWNlL3NpZ25hbHIvc2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEtBQUssT0FBTyxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3ZELE9BQU8sRUFHTCxtQkFBbUIsRUFDbkIsY0FBYyxFQUNkLGNBQWMsRUFDZCxnQkFBZ0IsR0FDakIsTUFBTSwyQ0FBMkMsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUM1RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQzs7QUFFMUU7Ozs7R0FJRztBQUlILE1BQU0sT0FBTyxxQkFBcUI7SUFIbEM7UUFJVSxrQkFBYSxHQUFpQyxJQUFJLENBQUM7UUFFM0Qsa0JBQWtCO1FBQ1QsMEJBQXFCLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFFL0QsZ0JBQWdCO1FBQ1Asd0JBQW1CLEdBQUcsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFFM0QsNkJBQTZCO1FBQ3BCLG9CQUFlLEdBQUcsTUFBTSxDQUFrQixnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVsRiwyREFBMkQ7UUFDbEQs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YixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7c0ZBdFJVLHFCQUFxQjt1RUFBckIscUJBQXFCLFdBQXJCLHFCQUFxQixtQkFGcEIsTUFBTTs7aUZBRVAscUJBQXFCO2NBSGpDLFVBQVU7ZUFBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGluamVjdCwgSW5qZWN0YWJsZSwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCAqIGFzIHNpZ25hbFIgZnJvbSAnQG1pY3Jvc29mdC9zaWduYWxyJztcclxuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBDb21tb24gfSBmcm9tICcuLi8uLi8uLi9hcHAvY29uc3RhbnRzL2NvbW1vbic7XHJcbmltcG9ydCB7XHJcbiAgQ29ubmVjdGlvblN0YXRlLFxyXG4gIENydWROb3RpZmljYXRpb24sXHJcbiAgU0lHTkFMUl9IVUJfTUVUSE9EUyxcclxuICBTSUdOQUxSX0VWRU5UUyxcclxuICBDUlVEX09QRVJBVElPTixcclxuICBDT05ORUNUSU9OX1NUQVRFLFxyXG59IGZyb20gJy4uLy4uLy4uL2FwcC9pbnRlcmZhY2VzL3NpZ25hbHIuaW50ZXJmYWNlJztcclxuaW1wb3J0IHsgU3RvcmFnZUNvbnN0YW50cyB9IGZyb20gJy4uLy4uLy4uL2FwcC9jb25zdGFudHMvc3RvcmFnZS1jb25zdGFudHMnO1xyXG5pbXBvcnQgeyBTZXNzaW9uU3RvcmFnZVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9hdXRoL3Nlc3Npb24tc3RvcmFnZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgTG9jYWxTdG9yYWdlU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2F1dGgvbG9jYWwtc3RvcmFnZS5zZXJ2aWNlJztcclxuXHJcbi8qKlxyXG4gKiBTaWduYWxSIEluZnJhc3RydWN0dXJlIFNlcnZpY2VcclxuICogSGFuZGxlcyBsb3ctbGV2ZWwgV2ViU29ja2V0IGNvbm5lY3Rpb24sIGdyb3VwIG1hbmFnZW1lbnQsIGFuZCByZWNvbm5lY3Rpb25cclxuICogSW50ZXJuYWwgdXNlIG9ubHkgLSBjb21wb25lbnRzIHNob3VsZCB1c2UgU2lnbmFsUlNlcnZpY2UgaW5zdGVhZFxyXG4gKi9cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIFNpZ25hbFJJbmZyYXN0cnVjdHVyZSB7XHJcbiAgcHJpdmF0ZSBodWJDb25uZWN0aW9uOiBzaWduYWxSLkh1YkNvbm5lY3Rpb24gfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLy8gU2Vzc2lvbiBzdG9yYWdlXHJcbiAgcmVhZG9ubHkgc2Vzc2lvblN0b3JhZ2VTZXJ2aWNlID0gaW5qZWN0KFNlc3Npb25TdG9yYWdlU2VydmljZSk7XHJcblxyXG4gIC8vIGxvY2FsIHN0b3JhZ2VcclxuICByZWFkb25seSBsb2NhbFN0b3JhZ2VTZXJ2aWNlID0gaW5qZWN0KExvY2FsU3RvcmFnZVNlcnZpY2UpO1xyXG5cclxuICAvLyBDb25uZWN0aW9uIHN0YXRlIGFzIHNpZ25hbFxyXG4gIHJlYWRvbmx5IGNvbm5lY3Rpb25TdGF0ZSA9IHNpZ25hbDxDb25uZWN0aW9uU3RhdGU+KENPTk5FQ1RJT05fU1RBVEUuRElTQ09OTkVDVEVEKTtcclxuXHJcbiAgLy8gTm90aWZpY2F0aW9uIHN0cmVhbSAoaW50ZXJuYWwgLSBlbWl0cyB0byBTaWduYWxSU2VydmljZSlcclxuICByZWFkb25seSBub3RpZmljYXRpb25zJCA9IG5ldyBTdWJqZWN0PENydWROb3RpZmljYXRpb24+KCk7XHJcblxyXG4gIC8vIFRyYWNrIGFjdGl2ZSBncm91cHMgdG8gcmVqb2luIGFmdGVyIHJlY29ubmVjdGlvblxyXG4gIHByaXZhdGUgYWN0aXZlR3JvdXBzID0gbmV3IFNldDxzdHJpbmc+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEhlbHBlciBtZXRob2QgdG8gZ2V0IHZhbHVlIGZyb20gc3RvcmFnZVxyXG4gICAqIEBwYXJhbSB0eXBlIFRoZSB0eXBlIG9mIHN0b3JhZ2UsICdTZXNzaW9uJyBvciAnTG9jYWwnXHJcbiAgICogQHBhcmFtIGtleSBUaGUga2V5IHRvIHJldHJpZXZlIHRoZSB2YWx1ZSBmb3JcclxuICAgKiBAcmV0dXJucyBUaGUgdmFsdWUgZnJvbSBzdG9yYWdlLCBvciBudWxsIGlmIG5vdCBhdmFpbGFibGVcclxuICAgKi9cclxuICBwcml2YXRlIGdldEZyb21TdG9yYWdlKHR5cGU6IHN0cmluZywga2V5OiBzdHJpbmcpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgIGxldCBpbmZvOiBhbnkgPSBudWxsO1xyXG5cclxuICAgICAgaWYgKHR5cGUgPT09ICdTZXNzaW9uJykge1xyXG4gICAgICAgIC8vIEdldCB2YWx1ZSBmcm9tIHNlc3Npb24gc3RvcmFnZVxyXG4gICAgICAgIGluZm8gPSB0aGlzLnNlc3Npb25TdG9yYWdlU2VydmljZS5nZXRTZXNzaW9uU3RvcmFnZShrZXkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodHlwZSA9PT0gJ0xvY2FsJykge1xyXG4gICAgICAgIC8vIEdldCB2YWx1ZSBmcm9tIGxvY2FsIHN0b3JhZ2VcclxuICAgICAgICBpbmZvID0gdGhpcy5sb2NhbFN0b3JhZ2VTZXJ2aWNlLmdldExvY2FsU3RvcmFnZShrZXkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaW5mbyAmJiB0eXBlb2YgaW5mbyA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAvLyBQYXJzZSB0aGUgdmFsdWUgaWYgaXQncyBhIHN0cmluZ1xyXG4gICAgICAgIGluZm8gPSBKU09OLnBhcnNlKGluZm8pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gaW5mbztcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIC8vIExvZyBlcnJvciBpZiBmYWlsZWQgdG8gZ2V0IHZhbHVlIGZyb20gc3RvcmFnZVxyXG4gICAgICBjb25zb2xlLndhcm4oJ0ZhaWxlZCB0byBnZXQgY3VycmVudCBhcHAgSUQgZnJvbSBzZXNzaW9uOicsIGVycm9yKTtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgYXBwSWQoKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICBjb25zdCBhcHBJbmZvID0gdGhpcy5nZXRGcm9tU3RvcmFnZSgnU2Vzc2lvbicsIFN0b3JhZ2VDb25zdGFudHMuYXBwSW5mbyk7XHJcbiAgICByZXR1cm4gYXBwSW5mbz8uSWQgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCBlbnZpcm9ubWVudElkKCk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgZW52SW5mbyA9IHRoaXMuZ2V0RnJvbVN0b3JhZ2UoJ1Nlc3Npb24nLCBTdG9yYWdlQ29uc3RhbnRzLmVudmlyb25tZW50SW5mbyk7XHJcbiAgICByZXR1cm4gZW52SW5mbz8uSWQgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCB0ZW5hbnRJZCgpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IHRlbmFudEluZm8gPSB0aGlzLmdldEZyb21TdG9yYWdlKCdMb2NhbCcsIFN0b3JhZ2VDb25zdGFudHMub3JnSW5mbyk7XHJcbiAgICByZXR1cm4gdGVuYW50SW5mbz8uSWQgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCB0b2tlbigpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IGF1dGhJbmZvID0gdGhpcy5nZXRGcm9tU3RvcmFnZSgnTG9jYWwnLCBTdG9yYWdlQ29uc3RhbnRzLnRva2VuSW5mbyk7XHJcbiAgICByZXR1cm4gYXV0aEluZm8/LnRva2VuIHx8IG51bGw7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb25uZWN0IHRvIFNpZ25hbFIgaHViXHJcbiAgICovXHJcbiAgYXN5bmMgY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICh0aGlzLmh1YkNvbm5lY3Rpb24/LnN0YXRlID09PSBzaWduYWxSLkh1YkNvbm5lY3Rpb25TdGF0ZS5Db25uZWN0ZWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEdldCBodWIgVVJMIGZyb20gQ29tbW9uIChzZXQgZHVyaW5nIGFwcCBpbml0aWFsaXphdGlvbiB2aWEgQ29tbW9uLmluaXQoKSlcclxuICAgIGNvbnN0IGh1YlVybCA9IENvbW1vbi5zaWduYWxSSHViVXJsO1xyXG5cclxuICAgIGlmICghaHViVXJsKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1tTaWduYWxSXSBIdWIgVVJMIG5vdCBjb25maWd1cmVkLiBNYWtlIHN1cmUgQ29tbW9uLmluaXQoKSBpcyBjYWxsZWQgd2l0aCBlbnZpcm9ubWVudC4nKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RJTkcpO1xyXG5cclxuICAgICAgdGhpcy5odWJDb25uZWN0aW9uID0gbmV3IHNpZ25hbFIuSHViQ29ubmVjdGlvbkJ1aWxkZXIoKVxyXG4gICAgICAgIC53aXRoVXJsKGh1YlVybCwge1xyXG4gICAgICAgICAgYWNjZXNzVG9rZW5GYWN0b3J5OiAoKSA9PiB0aGlzLnRva2VuIHx8ICcnLFxyXG4gICAgICAgICAgc2tpcE5lZ290aWF0aW9uOiBmYWxzZSxcclxuICAgICAgICAgIHRyYW5zcG9ydDogc2lnbmFsUi5IdHRwVHJhbnNwb3J0VHlwZS5XZWJTb2NrZXRzIHwgc2lnbmFsUi5IdHRwVHJhbnNwb3J0VHlwZS5TZXJ2ZXJTZW50RXZlbnRzLFxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLndpdGhBdXRvbWF0aWNSZWNvbm5lY3Qoe1xyXG4gICAgICAgICAgbmV4dFJldHJ5RGVsYXlJbk1pbGxpc2Vjb25kczogKHJldHJ5Q29udGV4dDogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIC8vIEV4cG9uZW50aWFsIGJhY2tvZmY6IDBzLCAycywgMTBzLCAzMHMsIG1heCA2MHNcclxuICAgICAgICAgICAgaWYgKHJldHJ5Q29udGV4dC5lbGFwc2VkTWlsbGlzZWNvbmRzIDwgNjAwMDApIHtcclxuICAgICAgICAgICAgICByZXR1cm4gTWF0aC5taW4oMTAwMCAqIE1hdGgucG93KDIsIHJldHJ5Q29udGV4dC5wcmV2aW91c1JldHJ5Q291bnQpLCA2MDAwMCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vIFN0b3AgcmV0cnlpbmcgYWZ0ZXIgMSBtaW51dGVcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgfSlcclxuICAgICAgICAuY29uZmlndXJlTG9nZ2luZyhzaWduYWxSLkxvZ0xldmVsLkluZm9ybWF0aW9uKVxyXG4gICAgICAgIC5idWlsZCgpO1xyXG5cclxuICAgICAgdGhpcy5yZWdpc3RlckV2ZW50SGFuZGxlcnMoKTtcclxuICAgICAgdGhpcy5yZWdpc3RlckNvbm5lY3Rpb25MaWZlY3ljbGUoKTtcclxuXHJcbiAgICAgIGF3YWl0IHRoaXMuaHViQ29ubmVjdGlvbi5zdGFydCgpO1xyXG5cclxuICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KENPTk5FQ1RJT05fU1RBVEUuQ09OTkVDVEVEKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkZBSUxFRCk7XHJcblxyXG4gICAgICAvLyBSZXRyeSBhZnRlciAxIG1pbnV0ZVxyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuY29ubmVjdCgpLCA2MCAqIDEwMDApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVnaXN0ZXIgU2lnbmFsUiBldmVudCBoYW5kbGVycyBmb3IgQ1JVRCBub3RpZmljYXRpb25zXHJcbiAgICovXHJcbiAgcHJpdmF0ZSByZWdpc3RlckV2ZW50SGFuZGxlcnMoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuaHViQ29ubmVjdGlvbikgcmV0dXJuO1xyXG5cclxuICAgIC8vIElOU0VSVCBub3RpZmljYXRpb25zXHJcbiAgICB0aGlzLmh1YkNvbm5lY3Rpb24ub24oU0lHTkFMUl9FVkVOVFMuSU5TRVJUX0NPTVBMRVRFRCwgKG5vdGlmaWNhdGlvbjogQ3J1ZE5vdGlmaWNhdGlvbikgPT4ge1xyXG4gICAgICBjb25zdCBlbnJpY2hlZCA9IHsgLi4ubm90aWZpY2F0aW9uLCBvcGVyYXRpb246IENSVURfT1BFUkFUSU9OLklOU0VSVCwgcmVjZWl2ZWRBdDogbmV3IERhdGUoKSB9O1xyXG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMkLm5leHQoZW5yaWNoZWQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gVVBEQVRFIG5vdGlmaWNhdGlvbnNcclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbihTSUdOQUxSX0VWRU5UUy5VUERBVEVfQ09NUExFVEVELCAobm90aWZpY2F0aW9uOiBDcnVkTm90aWZpY2F0aW9uKSA9PiB7XHJcbiAgICAgIGNvbnN0IGVucmljaGVkID0geyAuLi5ub3RpZmljYXRpb24sIG9wZXJhdGlvbjogQ1JVRF9PUEVSQVRJT04uVVBEQVRFLCByZWNlaXZlZEF0OiBuZXcgRGF0ZSgpIH07XHJcbiAgICAgIHRoaXMubm90aWZpY2F0aW9ucyQubmV4dChlbnJpY2hlZCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBERUxFVEUgbm90aWZpY2F0aW9uc1xyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9uKFNJR05BTFJfRVZFTlRTLkRFTEVURV9DT01QTEVURUQsIChub3RpZmljYXRpb246IENydWROb3RpZmljYXRpb24pID0+IHtcclxuICAgICAgY29uc3QgZW5yaWNoZWQgPSB7IC4uLm5vdGlmaWNhdGlvbiwgb3BlcmF0aW9uOiBDUlVEX09QRVJBVElPTi5ERUxFVEUsIHJlY2VpdmVkQXQ6IG5ldyBEYXRlKCkgfTtcclxuICAgICAgdGhpcy5ub3RpZmljYXRpb25zJC5uZXh0KGVucmljaGVkKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVnaXN0ZXIgY29ubmVjdGlvbiBsaWZlY3ljbGUgaGFuZGxlcnNcclxuICAgKi9cclxuICBwcml2YXRlIHJlZ2lzdGVyQ29ubmVjdGlvbkxpZmVjeWNsZSgpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5odWJDb25uZWN0aW9uKSByZXR1cm47XHJcblxyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9ucmVjb25uZWN0aW5nKCgpID0+IHtcclxuICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KENPTk5FQ1RJT05fU1RBVEUuUkVDT05ORUNUSU5HKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbnJlY29ubmVjdGVkKCgpID0+IHtcclxuICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KENPTk5FQ1RJT05fU1RBVEUuQ09OTkVDVEVEKTtcclxuXHJcbiAgICAgIC8vIFJlam9pbiBhbGwgZ3JvdXBzIGFmdGVyIHJlY29ubmVjdGlvblxyXG4gICAgICB0aGlzLnJlam9pbkdyb3VwcygpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9uY2xvc2UoKCkgPT4ge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5ESVNDT05ORUNURUQpO1xyXG5cclxuICAgICAgLy8gVHJ5IHRvIHJlY29ubmVjdFxyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuY29ubmVjdCgpLCA2MCAqIDEwMDApO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBKb2luIFNpZ25hbFIgZ3JvdXAgZm9yIGFuIEFwcE9iamVjdFxyXG4gICAqL1xyXG4gIGFzeW5jIGpvaW5Hcm91cChhcHBPYmplY3RJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAoIXRoaXMuaHViQ29ubmVjdGlvbiB8fCB0aGlzLmh1YkNvbm5lY3Rpb24uc3RhdGUgIT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgaWYgKCF0aGlzLnRlbmFudElkIHx8ICF0aGlzLmFwcElkIHx8ICF0aGlzLmVudmlyb25tZW50SWQgfHwgIWFwcE9iamVjdElkKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBhd2FpdCB0aGlzLmh1YkNvbm5lY3Rpb24uaW52b2tlKFxyXG4gICAgICAgIFNJR05BTFJfSFVCX01FVEhPRFMuSk9JTl9HUk9VUCxcclxuICAgICAgICB0aGlzLnRlbmFudElkLFxyXG4gICAgICAgIHRoaXMuYXBwSWQsXHJcbiAgICAgICAgdGhpcy5lbnZpcm9ubWVudElkLFxyXG4gICAgICAgIGFwcE9iamVjdElkXHJcbiAgICAgICk7XHJcblxyXG4gICAgICAvLyBUcmFjayB0aGlzIGdyb3VwIGZvciByZWNvbm5lY3Rpb25cclxuICAgICAgdGhpcy5hY3RpdmVHcm91cHMuYWRkKGFwcE9iamVjdElkKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFtTaWduYWxSXSBGYWlsZWQgdG8gam9pbiBncm91cDogJHthcHBPYmplY3RJZH1gLCBlcnJvcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMZWF2ZSBTaWduYWxSIGdyb3VwXHJcbiAgICovXHJcbiAgYXN5bmMgbGVhdmVHcm91cChhcHBPYmplY3RJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAoIXRoaXMuaHViQ29ubmVjdGlvbiB8fCB0aGlzLmh1YkNvbm5lY3Rpb24uc3RhdGUgIT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZCkge1xyXG4gICAgICAvLyBSZW1vdmUgZnJvbSB0cmFja2luZyBldmVuIGlmIG5vdCBjb25uZWN0ZWRcclxuICAgICAgdGhpcy5hY3RpdmVHcm91cHMuZGVsZXRlKGFwcE9iamVjdElkKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy50ZW5hbnRJZCB8fCAhdGhpcy5hcHBJZCB8fCAhdGhpcy5lbnZpcm9ubWVudElkIHx8ICFhcHBPYmplY3RJZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgYXdhaXQgdGhpcy5odWJDb25uZWN0aW9uLmludm9rZShcclxuICAgICAgICBTSUdOQUxSX0hVQl9NRVRIT0RTLkxFQVZFX0dST1VQLFxyXG4gICAgICAgIHRoaXMudGVuYW50SWQsXHJcbiAgICAgICAgdGhpcy5hcHBJZCxcclxuICAgICAgICB0aGlzLmVudmlyb25tZW50SWQsXHJcbiAgICAgICAgYXBwT2JqZWN0SWRcclxuICAgICAgKTtcclxuXHJcbiAgICAgIC8vIFJlbW92ZSBmcm9tIHRyYWNraW5nXHJcbiAgICAgIHRoaXMuYWN0aXZlR3JvdXBzLmRlbGV0ZShhcHBPYmplY3RJZCk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGBbU2lnbmFsUl0gRmFpbGVkIHRvIGxlYXZlIGdyb3VwOiAke2FwcE9iamVjdElkfWAsIGVycm9yKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlam9pbiBhbGwgYWN0aXZlIGdyb3VwcyBhZnRlciByZWNvbm5lY3Rpb25cclxuICAgKiBUaGlzIGVuc3VyZXMgY29tcG9uZW50cyBjb250aW51ZSByZWNlaXZpbmcgbm90aWZpY2F0aW9ucyBhZnRlciBuZXR3b3JrIGludGVycnVwdGlvblxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgcmVqb2luR3JvdXBzKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgaWYgKHRoaXMuYWN0aXZlR3JvdXBzLnNpemUgPT09IDApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEdldCBsaXN0IG9mIGdyb3VwcyB0byByZWpvaW5cclxuICAgIGNvbnN0IGdyb3VwcyA9IEFycmF5LmZyb20odGhpcy5hY3RpdmVHcm91cHMpO1xyXG5cclxuICAgIC8vIENsZWFyIHRoZSBzZXQgKHdpbGwgYmUgcmUtYWRkZWQgZHVyaW5nIGpvaW5Hcm91cClcclxuICAgIHRoaXMuYWN0aXZlR3JvdXBzLmNsZWFyKCk7XHJcblxyXG4gICAgLy8gUmVqb2luIGVhY2ggZ3JvdXBcclxuICAgIGZvciAoY29uc3QgYXBwT2JqZWN0SWQgb2YgZ3JvdXBzKSB7XHJcbiAgICAgIGF3YWl0IHRoaXMuam9pbkdyb3VwKGFwcE9iamVjdElkKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIGNvbm5lY3RlZFxyXG4gICAqL1xyXG4gIGlzQ29ubmVjdGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuaHViQ29ubmVjdGlvbj8uc3RhdGUgPT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERpc2Nvbm5lY3QgZnJvbSBTaWduYWxSIGh1YiAoY2xlYW51cClcclxuICAgKi9cclxuICBhc3luYyBkaXNjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgaWYgKHRoaXMuaHViQ29ubmVjdGlvbikge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGF3YWl0IHRoaXMuaHViQ29ubmVjdGlvbi5zdG9wKCk7XHJcbiAgICAgICAgdGhpcy5odWJDb25uZWN0aW9uID0gbnVsbDtcclxuICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5ESVNDT05ORUNURUQpO1xyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tTaWduYWxSXSBFcnJvciBkdXJpbmcgZGlzY29ubmVjdDonLCBlcnJvcik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBhY3RpdmUgZ3JvdXBzIChmb3IgZGVidWdnaW5nKVxyXG4gICAqL1xyXG4gIGdldEFjdGl2ZUdyb3VwcygpOiBzdHJpbmdbXSB7XHJcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmFjdGl2ZUdyb3Vwcyk7XHJcbiAgfVxyXG59Il19
@@ -0,0 +1,207 @@
1
+ import { Injectable, inject, computed } from '@angular/core';
2
+ import { SignalRInfrastructure } from './signalr-infrastructure.service';
3
+ import { OperationTrackerService } from './operation-tracker.service';
4
+ import { CONNECTION_STATE, } from '../../../app/interfaces/signalr.interface';
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * SignalR Service
8
+ * Public API for:
9
+ * 1. Components to register for real-time CRUD notifications
10
+ * 2. Services (TabFormioService) to track async operations
11
+ *
12
+ * Usage in components:
13
+ * ```typescript
14
+ * ngOnInit() {
15
+ * this.signalRService.register(
16
+ * this.componentId,
17
+ * this.appObjectId,
18
+ * (notification) => this.handleNotification(notification)
19
+ * );
20
+ * }
21
+ *
22
+ * ngOnDestroy() {
23
+ * this.signalRService.unregister(this.componentId, this.appObjectId);
24
+ * }
25
+ * ```
26
+ *
27
+ * Usage in services (TabFormioService):
28
+ * ```typescript
29
+ * const correlationId = response.correlationId;
30
+ * this.signalRService.waitForOperation(correlationId).subscribe(notification => {
31
+ * // Handle completed operation
32
+ * });
33
+ * ```
34
+ */
35
+ export class SignalRService {
36
+ constructor() {
37
+ this.infrastructure = inject(SignalRInfrastructure);
38
+ this.operationTracker = inject(OperationTrackerService);
39
+ // Registry: Map<appObjectId, Map<componentId, callback>>
40
+ this.componentRegistry = new Map();
41
+ /**
42
+ * Get connection state (for UI indicators)
43
+ */
44
+ this.connectionState = this.infrastructure.connectionState;
45
+ /**
46
+ * Check if currently connected
47
+ */
48
+ this.isConnected = computed(() => this.connectionState() === CONNECTION_STATE.CONNECTED);
49
+ // Listen to notifications from infrastructure and route them
50
+ this.infrastructure.notifications$.subscribe((notification) => {
51
+ // 1. Check if this is a tracked async operation (processRequest)
52
+ this.operationTracker.handleNotification(notification);
53
+ // 2. Also notify components subscribed to this appObjectId (Grid, etc.)
54
+ this.notifyComponents(notification);
55
+ });
56
+ }
57
+ /**
58
+ * Establish a connection to the SignalR hub
59
+ *
60
+ * This method is idempotent - if the connection is already established, it will not be re-established.
61
+ * Hub URL is read from Common.signalRHubUrl (set during app initialization via Common.init())
62
+ */
63
+ connect() {
64
+ this.infrastructure.connect();
65
+ }
66
+ /**
67
+ * Register component for real-time notifications
68
+ *
69
+ * @param componentId - Unique component identifier (generated by component)
70
+ * @param appObjectId - AppObject ID to subscribe to
71
+ * @param callback - Function to call when notification received
72
+ */
73
+ register(componentId, appObjectId, callback) {
74
+ // Initialize map for this AppObject if doesn't exist
75
+ if (!this.componentRegistry.has(appObjectId)) {
76
+ this.componentRegistry.set(appObjectId, new Map());
77
+ }
78
+ const components = this.componentRegistry.get(appObjectId);
79
+ // First component for this AppObject? Join SignalR group
80
+ if (components.size === 0) {
81
+ this.infrastructure.joinGroup(appObjectId);
82
+ }
83
+ // Add component to registry
84
+ components.set(componentId, callback);
85
+ }
86
+ /**
87
+ * Unregister component (cleanup on component destroy)
88
+ *
89
+ * @param componentId - Component identifier to remove
90
+ * @param appObjectId - AppObject ID to unsubscribe from
91
+ */
92
+ unregister(componentId, appObjectId) {
93
+ const components = this.componentRegistry.get(appObjectId);
94
+ if (!components) {
95
+ return;
96
+ }
97
+ // Remove component from registry
98
+ components.delete(componentId);
99
+ // Last component for this AppObject? Leave SignalR group
100
+ if (components.size === 0) {
101
+ this.infrastructure.leaveGroup(appObjectId);
102
+ this.componentRegistry.delete(appObjectId);
103
+ }
104
+ }
105
+ /**
106
+ * Wait for specific async operation to complete
107
+ * Used by TabFormioService for async processRequest operations
108
+ *
109
+ * @param correlationId - Correlation ID from backend response
110
+ * @param timeout - Optional timeout in milliseconds
111
+ * @returns Observable that emits when operation completes
112
+ */
113
+ waitForOperation(correlationId, timeout) {
114
+ return this.operationTracker.waitForOperation(correlationId, timeout);
115
+ }
116
+ /**
117
+ * Register async operation for tracking
118
+ * Optional - waitForOperation handles registration automatically
119
+ *
120
+ * @param operation - Pending operation details
121
+ */
122
+ registerOperation(operation) {
123
+ this.operationTracker.registerOperation(operation);
124
+ }
125
+ /**
126
+ * Check if operation is pending
127
+ */
128
+ isOperationPending(correlationId) {
129
+ return this.operationTracker.isPending(correlationId);
130
+ }
131
+ /**
132
+ * Notify all registered components for an AppObject
133
+ * Called when notification received from SignalR hub
134
+ */
135
+ notifyComponents(notification) {
136
+ const components = this.componentRegistry.get(notification.appObjectId);
137
+ if (!components || components.size === 0) {
138
+ // No components registered for this AppObject - ignore notification
139
+ return;
140
+ }
141
+ // Call each component's callback
142
+ components.forEach((callback, componentId) => {
143
+ try {
144
+ callback(notification);
145
+ }
146
+ catch (error) {
147
+ console.error(`[SignalR Service] Callback failed for component ${componentId}:`, error);
148
+ }
149
+ });
150
+ }
151
+ /**
152
+ * Get active AppObject groups (for debugging)
153
+ */
154
+ getActiveGroups() {
155
+ return Array.from(this.componentRegistry.keys());
156
+ }
157
+ /**
158
+ * Get component count for an AppObject (for debugging)
159
+ */
160
+ getComponentCount(appObjectId) {
161
+ return this.componentRegistry.get(appObjectId)?.size || 0;
162
+ }
163
+ /**
164
+ * Get total registered components across all AppObjects (for debugging)
165
+ */
166
+ getTotalComponentCount() {
167
+ let total = 0;
168
+ this.componentRegistry.forEach((components) => {
169
+ total += components.size;
170
+ });
171
+ return total;
172
+ }
173
+ /**
174
+ * Get registry state (for debugging)
175
+ */
176
+ getRegistryState() {
177
+ const state = [];
178
+ this.componentRegistry.forEach((components, appObjectId) => {
179
+ state.push({
180
+ appObjectId,
181
+ componentCount: components.size,
182
+ });
183
+ });
184
+ return state;
185
+ }
186
+ /**
187
+ * Get pending operations count (for debugging)
188
+ */
189
+ getPendingOperationsCount() {
190
+ return this.operationTracker.getPendingCount();
191
+ }
192
+ /**
193
+ * Get all pending operations (for debugging)
194
+ */
195
+ getPendingOperations() {
196
+ return this.operationTracker.getAllPending();
197
+ }
198
+ static { this.ɵfac = function SignalRService_Factory(t) { return new (t || SignalRService)(); }; }
199
+ static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: SignalRService, factory: SignalRService.ɵfac, providedIn: 'root' }); }
200
+ }
201
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SignalRService, [{
202
+ type: Injectable,
203
+ args: [{
204
+ providedIn: 'root',
205
+ }]
206
+ }], () => [], null); })();
207
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9kYXRhLWFjY2Vzcy9zcmMvbGliL3RhYi1jb3JlLXV0aWxpdHkvY29yZS9zZXJ2aWNlL3NpZ25hbHIvc2lnbmFsci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU3RCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUN6RSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN0RSxPQUFPLEVBSUwsZ0JBQWdCLEdBQ2pCLE1BQU0sMkNBQTJDLENBQUM7O0FBRW5EOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNEJHO0FBSUgsTUFBTSxPQUFPLGNBQWM7SUFpQnpCO1FBaEJRLG1CQUFjLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDL0MscUJBQWdCLEdBQUcsTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUM7UUFFM0QseURBQXlEO1FBQ2pELHNCQUFpQixHQUFHLElBQUksR0FBRyxFQUE2QyxDQUFDO1FBRWpGOztXQUVHO1FBQ00sb0JBQWUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQztRQUUvRDs7V0FFRztRQUNNLGdCQUFXLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsS0FBSyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUczRiw2REFBNkQ7UUFDN0QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLENBQUMsWUFBWSxFQUFFLEVBQUU7WUFDNUQsaUVBQWlFO1lBQ2pFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsQ0FB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O0lBQy9DLENBQUM7K0VBNUxVLGNBQWM7dUVBQWQsY0FBYyxXQUFkLGNBQWMsbUJBRmIsTUFBTTs7aUZBRVAsY0FBYztjQUgxQixVQUFVO2VBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QsIGNvbXB1dGVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgU2lnbmFsUkluZnJhc3RydWN0dXJlIH0gZnJvbSAnLi9zaWduYWxyLWluZnJhc3RydWN0dXJlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBPcGVyYXRpb25UcmFja2VyU2VydmljZSB9IGZyb20gJy4vb3BlcmF0aW9uLXRyYWNrZXIuc2VydmljZSc7XHJcbmltcG9ydCB7XHJcbiAgQ3J1ZE5vdGlmaWNhdGlvbixcclxuICBOb3RpZmljYXRpb25DYWxsYmFjayxcclxuICBQZW5kaW5nT3BlcmF0aW9uLFxyXG4gIENPTk5FQ1RJT05fU1RBVEUsXHJcbn0gZnJvbSAnLi4vLi4vLi4vYXBwL2ludGVyZmFjZXMvc2lnbmFsci5pbnRlcmZhY2UnO1xyXG5cclxuLyoqXHJcbiAqIFNpZ25hbFIgU2VydmljZVxyXG4gKiBQdWJsaWMgQVBJIGZvcjpcclxuICogMS4gQ29tcG9uZW50cyB0byByZWdpc3RlciBmb3IgcmVhbC10aW1lIENSVUQgbm90aWZpY2F0aW9uc1xyXG4gKiAyLiBTZXJ2aWNlcyAoVGFiRm9ybWlvU2VydmljZSkgdG8gdHJhY2sgYXN5bmMgb3BlcmF0aW9uc1xyXG4gKlxyXG4gKiBVc2FnZSBpbiBjb21wb25lbnRzOlxyXG4gKiBgYGB0eXBlc2NyaXB0XHJcbiAqIG5nT25Jbml0KCkge1xyXG4gKiAgIHRoaXMuc2lnbmFsUlNlcnZpY2UucmVnaXN0ZXIoXHJcbiAqICAgICB0aGlzLmNvbXBvbmVudElkLFxyXG4gKiAgICAgdGhpcy5hcHBPYmplY3RJZCxcclxuICogICAgIChub3RpZmljYXRpb24pID0+IHRoaXMuaGFuZGxlTm90aWZpY2F0aW9uKG5vdGlmaWNhdGlvbilcclxuICogICApO1xyXG4gKiB9XHJcbiAqXHJcbiAqIG5nT25EZXN0cm95KCkge1xyXG4gKiAgIHRoaXMuc2lnbmFsUlNlcnZpY2UudW5yZWdpc3Rlcih0aGlzLmNvbXBvbmVudElkLCB0aGlzLmFwcE9iamVjdElkKTtcclxuICogfVxyXG4gKiBgYGBcclxuICpcclxuICogVXNhZ2UgaW4gc2VydmljZXMgKFRhYkZvcm1pb1NlcnZpY2UpOlxyXG4gKiBgYGB0eXBlc2NyaXB0XHJcbiAqIGNvbnN0IGNvcnJlbGF0aW9uSWQgPSByZXNwb25zZS5jb3JyZWxhdGlvbklkO1xyXG4gKiB0aGlzLnNpZ25hbFJTZXJ2aWNlLndhaXRGb3JPcGVyYXRpb24oY29ycmVsYXRpb25JZCkuc3Vic2NyaWJlKG5vdGlmaWNhdGlvbiA9PiB7XHJcbiAqICAgLy8gSGFuZGxlIGNvbXBsZXRlZCBvcGVyYXRpb25cclxuICogfSk7XHJcbiAqIGBgYFxyXG4gKi9cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIFNpZ25hbFJTZXJ2aWNlIHtcclxuICBwcml2YXRlIGluZnJhc3RydWN0dXJlID0gaW5qZWN0KFNpZ25hbFJJbmZyYXN0cnVjdHVyZSk7XHJcbiAgcHJpdmF0ZSBvcGVyYXRpb25UcmFja2VyID0gaW5qZWN0KE9wZXJhdGlvblRyYWNrZXJTZXJ2aWNlKTtcclxuXHJcbiAgLy8gUmVnaXN0cnk6IE1hcDxhcHBPYmplY3RJZCwgTWFwPGNvbXBvbmVudElkLCBjYWxsYmFjaz4+XHJcbiAgcHJpdmF0ZSBjb21wb25lbnRSZWdpc3RyeSA9IG5ldyBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBOb3RpZmljYXRpb25DYWxsYmFjaz4+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBjb25uZWN0aW9uIHN0YXRlIChmb3IgVUkgaW5kaWNhdG9ycylcclxuICAgKi9cclxuICByZWFkb25seSBjb25uZWN0aW9uU3RhdGUgPSB0aGlzLmluZnJhc3RydWN0dXJlLmNvbm5lY3Rpb25TdGF0ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgY3VycmVudGx5IGNvbm5lY3RlZFxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzQ29ubmVjdGVkID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb25uZWN0aW9uU3RhdGUoKSA9PT0gQ09OTkVDVElPTl9TVEFURS5DT05ORUNURUQpO1xyXG5cclxuICBjb25zdHJ1Y3RvcigpIHtcclxuICAgIC8vIExpc3RlbiB0byBub3RpZmljYXRpb25zIGZyb20gaW5mcmFzdHJ1Y3R1cmUgYW5kIHJvdXRlIHRoZW1cclxuICAgIHRoaXMuaW5mcmFzdHJ1Y3R1cmUubm90aWZpY2F0aW9ucyQuc3Vic2NyaWJlKChub3RpZmljYXRpb24pID0+IHtcclxuICAgICAgLy8gMS4gQ2hlY2sgaWYgdGhpcyBpcyBhIHRyYWNrZWQgYXN5bmMgb3BlcmF0aW9uIChwcm9jZXNzUmVxdWVzdClcclxuICAgICAgdGhpcy5vcGVyYXRpb25UcmFja2VyLmhhbmRsZU5vdGlmaWNhdGlvbihub3RpZmljYXRpb24pO1xyXG5cclxuICAgICAgLy8gMi4gQWxzbyBub3RpZnkgY29tcG9uZW50cyBzdWJzY3JpYmVkIHRvIHRoaXMgYXBwT2JqZWN0SWQgKEdyaWQsIGV0Yy4pXHJcbiAgICAgIHRoaXMubm90aWZ5Q29tcG9uZW50cyhub3RpZmljYXRpb24pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFc3RhYmxpc2ggYSBjb25uZWN0aW9uIHRvIHRoZSBTaWduYWxSIGh1YlxyXG4gICAqXHJcbiAgICogVGhpcyBtZXRob2QgaXMgaWRlbXBvdGVudCAtIGlmIHRoZSBjb25uZWN0aW9uIGlzIGFscmVhZHkgZXN0YWJsaXNoZWQsIGl0IHdpbGwgbm90IGJlIHJlLWVzdGFibGlzaGVkLlxyXG4gICAqIEh1YiBVUkwgaXMgcmVhZCBmcm9tIENvbW1vbi5zaWduYWxSSHViVXJsIChzZXQgZHVyaW5nIGFwcCBpbml0aWFsaXphdGlvbiB2aWEgQ29tbW9uLmluaXQoKSlcclxuICAgKi9cclxuICBjb25uZWN0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5pbmZyYXN0cnVjdHVyZS5jb25uZWN0KCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlciBjb21wb25lbnQgZm9yIHJlYWwtdGltZSBub3RpZmljYXRpb25zXHJcbiAgICpcclxuICAgKiBAcGFyYW0gY29tcG9uZW50SWQgLSBVbmlxdWUgY29tcG9uZW50IGlkZW50aWZpZXIgKGdlbmVyYXRlZCBieSBjb21wb25lbnQpXHJcbiAgICogQHBhcmFtIGFwcE9iamVjdElkIC0gQXBwT2JqZWN0IElEIHRvIHN1YnNjcmliZSB0b1xyXG4gICAqIEBwYXJhbSBjYWxsYmFjayAtIEZ1bmN0aW9uIHRvIGNhbGwgd2hlbiBub3RpZmljYXRpb24gcmVjZWl2ZWRcclxuICAgKi9cclxuICByZWdpc3Rlcihjb21wb25lbnRJZDogc3RyaW5nLCBhcHBPYmplY3RJZDogc3RyaW5nLCBjYWxsYmFjazogTm90aWZpY2F0aW9uQ2FsbGJhY2spOiB2b2lkIHtcclxuICAgIC8vIEluaXRpYWxpemUgbWFwIGZvciB0aGlzIEFwcE9iamVjdCBpZiBkb2Vzbid0IGV4aXN0XHJcbiAgICBpZiAoIXRoaXMuY29tcG9uZW50UmVnaXN0cnkuaGFzKGFwcE9iamVjdElkKSkge1xyXG4gICAgICB0aGlzLmNvbXBvbmVudFJlZ2lzdHJ5LnNldChhcHBPYmplY3RJZCwgbmV3IE1hcCgpKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBjb21wb25lbnRzID0gdGhpcy5jb21wb25lbnRSZWdpc3RyeS5nZXQoYXBwT2JqZWN0SWQpITtcclxuXHJcbiAgICAvLyBGaXJzdCBjb21wb25lbnQgZm9yIHRoaXMgQXBwT2JqZWN0PyBKb2luIFNpZ25hbFIgZ3JvdXBcclxuICAgIGlmIChjb21wb25lbnRzLnNpemUgPT09IDApIHtcclxuICAgICAgdGhpcy5pbmZyYXN0cnVjdHVyZS5qb2luR3JvdXAoYXBwT2JqZWN0SWQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEFkZCBjb21wb25lbnQgdG8gcmVnaXN0cnlcclxuICAgIGNvbXBvbmVudHMuc2V0KGNvbXBvbmVudElkLCBjYWxsYmFjayk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBVbnJlZ2lzdGVyIGNvbXBvbmVudCAoY2xlYW51cCBvbiBjb21wb25lbnQgZGVzdHJveSlcclxuICAgKlxyXG4gICAqIEBwYXJhbSBjb21wb25lbnRJZCAtIENvbXBvbmVudCBpZGVudGlmaWVyIHRvIHJlbW92ZVxyXG4gICAqIEBwYXJhbSBhcHBPYmplY3RJZCAtIEFwcE9iamVjdCBJRCB0byB1bnN1YnNjcmliZSBmcm9tXHJcbiAgICovXHJcbiAgdW5yZWdpc3Rlcihjb21wb25lbnRJZDogc3RyaW5nLCBhcHBPYmplY3RJZDogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBjb25zdCBjb21wb25lbnRzID0gdGhpcy5jb21wb25lbnRSZWdpc3RyeS5nZXQoYXBwT2JqZWN0SWQpO1xyXG4gICAgaWYgKCFjb21wb25lbnRzKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBSZW1vdmUgY29tcG9uZW50IGZyb20gcmVnaXN0cnlcclxuICAgIGNvbXBvbmVudHMuZGVsZXRlKGNvbXBvbmVudElkKTtcclxuXHJcbiAgICAvLyBMYXN0IGNvbXBvbmVudCBmb3IgdGhpcyBBcHBPYmplY3Q/IExlYXZlIFNpZ25hbFIgZ3JvdXBcclxuICAgIGlmIChjb21wb25lbnRzLnNpemUgPT09IDApIHtcclxuICAgICAgdGhpcy5pbmZyYXN0cnVjdHVyZS5sZWF2ZUdyb3VwKGFwcE9iamVjdElkKTtcclxuICAgICAgdGhpcy5jb21wb25lbnRSZWdpc3RyeS5kZWxldGUoYXBwT2JqZWN0SWQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogV2FpdCBmb3Igc3BlY2lmaWMgYXN5bmMgb3BlcmF0aW9uIHRvIGNvbXBsZXRlXHJcbiAgICogVXNlZCBieSBUYWJGb3JtaW9TZXJ2aWNlIGZvciBhc3luYyBwcm9jZXNzUmVxdWVzdCBvcGVyYXRpb25zXHJcbiAgICpcclxuICAgKiBAcGFyYW0gY29ycmVsYXRpb25JZCAtIENvcnJlbGF0aW9uIElEIGZyb20gYmFja2VuZCByZXNwb25zZVxyXG4gICAqIEBwYXJhbSB0aW1lb3V0IC0gT3B0aW9uYWwgdGltZW91dCBpbiBtaWxsaXNlY29uZHNcclxuICAgKiBAcmV0dXJucyBPYnNlcnZhYmxlIHRoYXQgZW1pdHMgd2hlbiBvcGVyYXRpb24gY29tcGxldGVzXHJcbiAgICovXHJcbiAgd2FpdEZvck9wZXJhdGlvbihjb3JyZWxhdGlvbklkOiBzdHJpbmcsIHRpbWVvdXQ/OiBudW1iZXIpOiBPYnNlcnZhYmxlPENydWROb3RpZmljYXRpb24+IHtcclxuICAgIHJldHVybiB0aGlzLm9wZXJhdGlvblRyYWNrZXIud2FpdEZvck9wZXJhdGlvbihjb3JyZWxhdGlvbklkLCB0aW1lb3V0KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlZ2lzdGVyIGFzeW5jIG9wZXJhdGlvbiBmb3IgdHJhY2tpbmdcclxuICAgKiBPcHRpb25hbCAtIHdhaXRGb3JPcGVyYXRpb24gaGFuZGxlcyByZWdpc3RyYXRpb24gYXV0b21hdGljYWxseVxyXG4gICAqXHJcbiAgICogQHBhcmFtIG9wZXJhdGlvbiAtIFBlbmRpbmcgb3BlcmF0aW9uIGRldGFpbHNcclxuICAgKi9cclxuICByZWdpc3Rlck9wZXJhdGlvbihvcGVyYXRpb246IFBlbmRpbmdPcGVyYXRpb24pOiB2b2lkIHtcclxuICAgIHRoaXMub3BlcmF0aW9uVHJhY2tlci5yZWdpc3Rlck9wZXJhdGlvbihvcGVyYXRpb24pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgb3BlcmF0aW9uIGlzIHBlbmRpbmdcclxuICAgKi9cclxuICBpc09wZXJhdGlvblBlbmRpbmcoY29ycmVsYXRpb25JZDogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5vcGVyYXRpb25UcmFja2VyLmlzUGVuZGluZyhjb3JyZWxhdGlvbklkKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE5vdGlmeSBhbGwgcmVnaXN0ZXJlZCBjb21wb25lbnRzIGZvciBhbiBBcHBPYmplY3RcclxuICAgKiBDYWxsZWQgd2hlbiBub3RpZmljYXRpb24gcmVjZWl2ZWQgZnJvbSBTaWduYWxSIGh1YlxyXG4gICAqL1xyXG4gIHByaXZhdGUgbm90aWZ5Q29tcG9uZW50cyhub3RpZmljYXRpb246IENydWROb3RpZmljYXRpb24pOiB2b2lkIHtcclxuICAgIGNvbnN0IGNvbXBvbmVudHMgPSB0aGlzLmNvbXBvbmVudFJlZ2lzdHJ5LmdldChub3RpZmljYXRpb24uYXBwT2JqZWN0SWQpO1xyXG5cclxuICAgIGlmICghY29tcG9uZW50cyB8fCBjb21wb25lbnRzLnNpemUgPT09IDApIHtcclxuICAgICAgLy8gTm8gY29tcG9uZW50cyByZWdpc3RlcmVkIGZvciB0aGlzIEFwcE9iamVjdCAtIGlnbm9yZSBub3RpZmljYXRpb25cclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENhbGwgZWFjaCBjb21wb25lbnQncyBjYWxsYmFja1xyXG4gICAgY29tcG9uZW50cy5mb3JFYWNoKChjYWxsYmFjaywgY29tcG9uZW50SWQpID0+IHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBjYWxsYmFjayhub3RpZmljYXRpb24pO1xyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFtTaWduYWxSIFNlcnZpY2VdIENhbGxiYWNrIGZhaWxlZCBmb3IgY29tcG9uZW50ICR7Y29tcG9uZW50SWR9OmAsIGVycm9yKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgYWN0aXZlIEFwcE9iamVjdCBncm91cHMgKGZvciBkZWJ1Z2dpbmcpXHJcbiAgICovXHJcbiAgZ2V0QWN0aXZlR3JvdXBzKCk6IHN0cmluZ1tdIHtcclxuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuY29tcG9uZW50UmVnaXN0cnkua2V5cygpKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBjb21wb25lbnQgY291bnQgZm9yIGFuIEFwcE9iamVjdCAoZm9yIGRlYnVnZ2luZylcclxuICAgKi9cclxuICBnZXRDb21wb25lbnRDb3VudChhcHBPYmplY3RJZDogc3RyaW5nKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLmNvbXBvbmVudFJlZ2lzdHJ5LmdldChhcHBPYmplY3RJZCk/LnNpemUgfHwgMDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0b3RhbCByZWdpc3RlcmVkIGNvbXBvbmVudHMgYWNyb3NzIGFsbCBBcHBPYmplY3RzIChmb3IgZGVidWdnaW5nKVxyXG4gICAqL1xyXG4gIGdldFRvdGFsQ29tcG9uZW50Q291bnQoKTogbnVtYmVyIHtcclxuICAgIGxldCB0b3RhbCA9IDA7XHJcbiAgICB0aGlzLmNvbXBvbmVudFJlZ2lzdHJ5LmZvckVhY2goKGNvbXBvbmVudHMpID0+IHtcclxuICAgICAgdG90YWwgKz0gY29tcG9uZW50cy5zaXplO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdG90YWw7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgcmVnaXN0cnkgc3RhdGUgKGZvciBkZWJ1Z2dpbmcpXHJcbiAgICovXHJcbiAgZ2V0UmVnaXN0cnlTdGF0ZSgpOiB7IGFwcE9iamVjdElkOiBzdHJpbmc7IGNvbXBvbmVudENvdW50OiBudW1iZXIgfVtdIHtcclxuICAgIGNvbnN0IHN0YXRlOiB7IGFwcE9iamVjdElkOiBzdHJpbmc7IGNvbXBvbmVudENvdW50OiBudW1iZXIgfVtdID0gW107XHJcblxyXG4gICAgdGhpcy5jb21wb25lbnRSZWdpc3RyeS5mb3JFYWNoKChjb21wb25lbnRzLCBhcHBPYmplY3RJZCkgPT4ge1xyXG4gICAgICBzdGF0ZS5wdXNoKHtcclxuICAgICAgICBhcHBPYmplY3RJZCxcclxuICAgICAgICBjb21wb25lbnRDb3VudDogY29tcG9uZW50cy5zaXplLFxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiBzdGF0ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBwZW5kaW5nIG9wZXJhdGlvbnMgY291bnQgKGZvciBkZWJ1Z2dpbmcpXHJcbiAgICovXHJcbiAgZ2V0UGVuZGluZ09wZXJhdGlvbnNDb3VudCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMub3BlcmF0aW9uVHJhY2tlci5nZXRQZW5kaW5nQ291bnQoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBhbGwgcGVuZGluZyBvcGVyYXRpb25zIChmb3IgZGVidWdnaW5nKVxyXG4gICAqL1xyXG4gIGdldFBlbmRpbmdPcGVyYXRpb25zKCk6IFBlbmRpbmdPcGVyYXRpb25bXSB7XHJcbiAgICByZXR1cm4gdGhpcy5vcGVyYXRpb25UcmFja2VyLmdldEFsbFBlbmRpbmcoKTtcclxuICB9XHJcbn0iXX0=
package/index.d.ts CHANGED
@@ -36,6 +36,7 @@ export * from './lib/tab-core-utility/app/interfaces/user.interface';
36
36
  export * from './lib/tab-core-utility/app/interfaces/orgInfo.interface';
37
37
  export * from './lib/tab-core-utility/app/interfaces/schema.interface';
38
38
  export * from './lib/tab-core-utility/app/interfaces/grid.interface';
39
+ export * from './lib/tab-core-utility/app/interfaces/signalr.interface';
39
40
  export * from './lib/tab-core-utility/app/models/api-query.class';
40
41
  export * from './lib/tab-core-utility/app/models/app-object.class';
41
42
  export * from './lib/tab-core-utility/app/models/common.class';
@@ -56,6 +57,9 @@ export * from './lib/tab-core-utility/core/service/translation.service';
56
57
  export * from './lib/tab-core-utility/core/service/notification.service';
57
58
  export * from './lib/tab-core-utility/core/service/confirmation.service';
58
59
  export * from './lib/tab-core-utility/core/service/encryption.service';
60
+ export * from './lib/tab-core-utility/core/service/signalr/signalr.service';
61
+ export * from './lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service';
62
+ export * from './lib/tab-core-utility/core/service/signalr/operation-tracker.service';
59
63
  export * from './lib/tab-core-utility/core/pipe/translate.pipe';
60
64
  export * from './lib/tab-core-utility/core/provider/translation.provider';
61
65
  export * from './lib/tab-core-utility/core/provider/notification.provider';
@@ -1,18 +1,15 @@
1
+ import type { APIServiceName } from '../interfaces/common.interface';
1
2
  export declare const API: {
2
3
  applicationIdentifier: string;
3
4
  applicationIdentifierForPMS: string;
4
5
  novuBackendUrl: string;
5
6
  novuSocketUrl: string;
6
- insert: string;
7
7
  bulkInsert: string;
8
- update: string;
9
- delete: string;
10
8
  select: string;
11
- getDSQ: string;
12
- getScreen: string;
13
- getListFromDsq: string;
9
+ screen: string;
10
+ listsGet: string;
14
11
  buildApp: string;
15
- getSchema: string;
12
+ metadataSchema: string;
16
13
  login: string;
17
14
  pluginUpload: string;
18
15
  getFile: string;
@@ -24,12 +21,12 @@ export declare const API: {
24
21
  multipleFileUpload: string;
25
22
  deleteFile: string;
26
23
  getMediaFile: string;
27
- getHistory: string;
24
+ auditGetHistory: string;
28
25
  changePassword: string;
29
26
  restpassword: string;
30
27
  getImage: string;
31
28
  pmjayImport: string;
32
- getScreenData: string;
29
+ screenData: string;
33
30
  processRequest: string;
34
31
  getNextStatus: string;
35
32
  updateStatus: string;
@@ -43,7 +40,7 @@ export declare const API: {
43
40
  registerAppObjects: string;
44
41
  languageResource: string;
45
42
  refreshToken: string;
46
- search: string;
43
+ globalSearch: string;
47
44
  cloneDsq: string;
48
45
  InsertScreenPerformanceAnalytics: string;
49
46
  GenerateHttpRequest: string;
@@ -63,4 +60,10 @@ export declare const API: {
63
60
  GetAllDocumnets: string;
64
61
  GetDocumentById: string;
65
62
  ExecuteWorkflow: string;
63
+ QueriesExecute: string;
64
+ QueriesSelect: string;
65
+ recordsInsert: string;
66
+ recordsUpdate: string;
67
+ recordsDelete: string;
66
68
  };
69
+ export declare const APIServices: Record<APIServiceName, APIServiceName>;
@@ -1,3 +1,4 @@
1
+ import { APIServiceUrls } from '../interfaces/common.interface';
1
2
  export declare class Common {
2
3
  static environmentName: string;
3
4
  static applicationCode: string;
@@ -7,5 +8,13 @@ export declare class Common {
7
8
  static tabAppObjectAccess: any;
8
9
  static staticToken: any;
9
10
  static i18n: any;
11
+ /** Microservice URLs configuration - NEW for microservices architecture */
12
+ static apiServiceUrls: APIServiceUrls;
13
+ /** SignalR hub URL for real-time notifications */
14
+ static signalRHubUrl: string;
15
+ /**
16
+ * Initialize the static variables
17
+ * Called once at application startup from the main app
18
+ */
10
19
  static init(environment: any): void;
11
20
  }
@@ -22,5 +22,5 @@ export declare const StorageConstants: {
22
22
  refreshTokenExpiry: string;
23
23
  appNavigationMapping: string;
24
24
  tokenInfo: string;
25
- Environment: string;
25
+ EnvironmentId: string;
26
26
  };