@techextensor/tab-core-utility 2.2.190 → 2.2.192
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.
- package/esm2022/index.mjs +1 -5
- package/esm2022/lib/tab-core-utility/app/constants/api-constants.mjs +15 -31
- package/esm2022/lib/tab-core-utility/app/constants/common.mjs +50 -14
- package/esm2022/lib/tab-core-utility/app/constants/storage-constants.mjs +3 -2
- package/esm2022/lib/tab-core-utility/app/crud/tab-blueprint.service.mjs +5 -5
- package/esm2022/lib/tab-core-utility/app/crud/tab-crud.service.mjs +54 -41
- package/esm2022/lib/tab-core-utility/app/crud/tab-delete.service.mjs +30 -84
- package/esm2022/lib/tab-core-utility/app/crud/tab-formio.service.mjs +12 -141
- package/esm2022/lib/tab-core-utility/app/crud/tab-get.service.mjs +41 -142
- package/esm2022/lib/tab-core-utility/app/crud/tab-insert.service.mjs +38 -89
- package/esm2022/lib/tab-core-utility/app/crud/tab-update.service.mjs +129 -159
- package/esm2022/lib/tab-core-utility/app/enums/query.enum.mjs +7 -7
- package/esm2022/lib/tab-core-utility/app/helpers/common/app.helpers.mjs +21 -28
- package/esm2022/lib/tab-core-utility/app/helpers/common/dsq.helpers.mjs +11 -9
- package/esm2022/lib/tab-core-utility/app/helpers/common/meta-data.helpers.mjs +13 -13
- package/esm2022/lib/tab-core-utility/app/helpers/common/req-res.helpers.mjs +45 -7
- package/esm2022/lib/tab-core-utility/app/helpers/common/where-clause.helpers.mjs +76 -79
- package/esm2022/lib/tab-core-utility/app/helpers/screen/grid.helpers.mjs +4 -8
- package/esm2022/lib/tab-core-utility/app/helpers/screen/media-upload.helpers.mjs +4 -4
- package/esm2022/lib/tab-core-utility/app/helpers/screen/screen.helpers.mjs +33 -8
- package/esm2022/lib/tab-core-utility/app/interfaces/common.interface.mjs +1 -1
- package/esm2022/lib/tab-core-utility/app/models/api-query.class.mjs +1 -39
- package/esm2022/lib/tab-core-utility/app/models/app-field.model.mjs +7 -36
- package/esm2022/lib/tab-core-utility/app/models/app-object.model.mjs +47 -84
- package/esm2022/lib/tab-core-utility/app/models/app-screen.model.mjs +13 -24
- package/esm2022/lib/tab-core-utility/app/models/data-source-query.model.mjs +23 -57
- package/esm2022/lib/tab-core-utility/app/models/filter.model.mjs +10 -21
- package/esm2022/lib/tab-core-utility/app/models/parameter.model.mjs +6 -12
- package/esm2022/lib/tab-core-utility/app/models/sort.model.mjs +4 -11
- package/esm2022/lib/tab-core-utility/app/utils/json.util.mjs +16 -17
- package/esm2022/lib/tab-core-utility/app/utils/req-res.util.mjs +55 -1
- package/esm2022/lib/tab-core-utility/app/utils/tab-app.util.mjs +164 -1
- package/esm2022/lib/tab-core-utility/core/http-client/api.service.mjs +1 -78
- package/index.d.ts +0 -4
- package/lib/tab-core-utility/app/constants/api-constants.d.ts +12 -19
- package/lib/tab-core-utility/app/constants/common.d.ts +0 -9
- package/lib/tab-core-utility/app/constants/storage-constants.d.ts +2 -1
- package/lib/tab-core-utility/app/crud/tab-blueprint.service.d.ts +2 -2
- package/lib/tab-core-utility/app/crud/tab-crud.service.d.ts +1 -8
- package/lib/tab-core-utility/app/crud/tab-delete.service.d.ts +10 -20
- package/lib/tab-core-utility/app/crud/tab-formio.service.d.ts +6 -33
- package/lib/tab-core-utility/app/crud/tab-get.service.d.ts +6 -48
- package/lib/tab-core-utility/app/crud/tab-insert.service.d.ts +21 -16
- package/lib/tab-core-utility/app/crud/tab-update.service.d.ts +19 -34
- package/lib/tab-core-utility/app/enums/query.enum.d.ts +6 -3
- package/lib/tab-core-utility/app/helpers/common/app.helpers.d.ts +9 -6
- package/lib/tab-core-utility/app/helpers/common/dsq.helpers.d.ts +0 -3
- package/lib/tab-core-utility/app/helpers/common/meta-data.helpers.d.ts +3 -3
- package/lib/tab-core-utility/app/helpers/common/req-res.helpers.d.ts +51 -7
- package/lib/tab-core-utility/app/helpers/common/where-clause.helpers.d.ts +0 -1
- package/lib/tab-core-utility/app/helpers/screen/grid.helpers.d.ts +1 -2
- package/lib/tab-core-utility/app/helpers/screen/media-upload.helpers.d.ts +1 -1
- package/lib/tab-core-utility/app/helpers/screen/screen.helpers.d.ts +0 -1
- package/lib/tab-core-utility/app/interfaces/common.interface.d.ts +2 -51
- package/lib/tab-core-utility/app/models/api-query.class.d.ts +9 -54
- package/lib/tab-core-utility/app/models/app-field.model.d.ts +2 -4
- package/lib/tab-core-utility/app/models/app-object.model.d.ts +3 -5
- package/lib/tab-core-utility/app/models/app-screen.model.d.ts +2 -2
- package/lib/tab-core-utility/app/models/data-source-query.model.d.ts +2 -7
- package/lib/tab-core-utility/app/models/filter.model.d.ts +2 -2
- package/lib/tab-core-utility/app/models/parameter.model.d.ts +2 -2
- package/lib/tab-core-utility/app/models/sort.model.d.ts +1 -1
- package/lib/tab-core-utility/app/utils/json.util.d.ts +2 -3
- package/lib/tab-core-utility/app/utils/req-res.util.d.ts +9 -1
- package/lib/tab-core-utility/app/utils/tab-app.util.d.ts +61 -0
- package/lib/tab-core-utility/core/http-client/api.service.d.ts +0 -46
- package/package.json +2 -3
- package/esm2022/lib/tab-core-utility/app/helpers/response.adapter.mjs +0 -38
- package/esm2022/lib/tab-core-utility/app/interfaces/signalr.interface.mjs +0 -42
- package/esm2022/lib/tab-core-utility/core/service/signalr/operation-tracker.service.mjs +0 -90
- package/esm2022/lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service.mjs +0 -268
- package/esm2022/lib/tab-core-utility/core/service/signalr/signalr.service.mjs +0 -207
- package/lib/tab-core-utility/app/helpers/response.adapter.d.ts +0 -22
- package/lib/tab-core-utility/app/interfaces/signalr.interface.d.ts +0 -84
- package/lib/tab-core-utility/core/service/signalr/operation-tracker.service.d.ts +0 -40
- package/lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service.d.ts +0 -73
- package/lib/tab-core-utility/core/service/signalr/signalr.service.d.ts +0 -122
package/esm2022/lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service.mjs
DELETED
|
@@ -1,268 +0,0 @@
|
|
|
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, (...args) => {
|
|
125
|
-
const notification = this.extractNotification(args);
|
|
126
|
-
const enriched = { ...notification, operation: CRUD_OPERATION.INSERT, receivedAt: new Date() };
|
|
127
|
-
this.notifications$.next(enriched);
|
|
128
|
-
});
|
|
129
|
-
// UPDATE notifications
|
|
130
|
-
this.hubConnection.on(SIGNALR_EVENTS.UPDATE_COMPLETED, (...args) => {
|
|
131
|
-
const notification = this.extractNotification(args);
|
|
132
|
-
const enriched = { ...notification, operation: CRUD_OPERATION.UPDATE, receivedAt: new Date() };
|
|
133
|
-
this.notifications$.next(enriched);
|
|
134
|
-
});
|
|
135
|
-
// DELETE notifications
|
|
136
|
-
this.hubConnection.on(SIGNALR_EVENTS.DELETE_COMPLETED, (...args) => {
|
|
137
|
-
const notification = this.extractNotification(args);
|
|
138
|
-
const enriched = { ...notification, operation: CRUD_OPERATION.DELETE, receivedAt: new Date() };
|
|
139
|
-
this.notifications$.next(enriched);
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Extract notification from SignalR callback args
|
|
144
|
-
* Handles both unwrapped (direct object) and wrapped ({ type, target, arguments }) formats
|
|
145
|
-
*/
|
|
146
|
-
extractNotification(args) {
|
|
147
|
-
const data = args[0];
|
|
148
|
-
// If SignalR didn't unwrap: data is raw SignalRMessage with { type, target, arguments: [...] }
|
|
149
|
-
if (data?.arguments && Array.isArray(data.arguments)) {
|
|
150
|
-
return data.arguments[0];
|
|
151
|
-
}
|
|
152
|
-
// If SignalR unwrapped: data is the notification directly
|
|
153
|
-
return data;
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Register connection lifecycle handlers
|
|
157
|
-
*/
|
|
158
|
-
registerConnectionLifecycle() {
|
|
159
|
-
if (!this.hubConnection)
|
|
160
|
-
return;
|
|
161
|
-
this.hubConnection.onreconnecting(() => {
|
|
162
|
-
this.connectionState.set(CONNECTION_STATE.RECONNECTING);
|
|
163
|
-
});
|
|
164
|
-
this.hubConnection.onreconnected(() => {
|
|
165
|
-
this.connectionState.set(CONNECTION_STATE.CONNECTED);
|
|
166
|
-
// Rejoin all groups after reconnection
|
|
167
|
-
this.rejoinGroups();
|
|
168
|
-
});
|
|
169
|
-
this.hubConnection.onclose(() => {
|
|
170
|
-
this.connectionState.set(CONNECTION_STATE.DISCONNECTED);
|
|
171
|
-
// Try to reconnect
|
|
172
|
-
setTimeout(() => this.connect(), 60 * 1000);
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Join SignalR group for an AppObject
|
|
177
|
-
*/
|
|
178
|
-
async joinGroup(appObjectId) {
|
|
179
|
-
if (!this.hubConnection || this.hubConnection.state !== signalR.HubConnectionState.Connected) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
try {
|
|
183
|
-
if (!this.tenantId || !this.appId || !this.environmentId || !appObjectId) {
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
await this.hubConnection.invoke(SIGNALR_HUB_METHODS.JOIN_GROUP, this.tenantId, this.appId, this.environmentId, appObjectId);
|
|
187
|
-
// Track this group for reconnection
|
|
188
|
-
this.activeGroups.add(appObjectId);
|
|
189
|
-
}
|
|
190
|
-
catch (error) {
|
|
191
|
-
console.error(`[SignalR] Failed to join group: ${appObjectId}`, error);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Leave SignalR group
|
|
196
|
-
*/
|
|
197
|
-
async leaveGroup(appObjectId) {
|
|
198
|
-
if (!this.hubConnection || this.hubConnection.state !== signalR.HubConnectionState.Connected) {
|
|
199
|
-
// Remove from tracking even if not connected
|
|
200
|
-
this.activeGroups.delete(appObjectId);
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
if (!this.tenantId || !this.appId || !this.environmentId || !appObjectId) {
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
try {
|
|
207
|
-
await this.hubConnection.invoke(SIGNALR_HUB_METHODS.LEAVE_GROUP, this.tenantId, this.appId, this.environmentId, appObjectId);
|
|
208
|
-
// Remove from tracking
|
|
209
|
-
this.activeGroups.delete(appObjectId);
|
|
210
|
-
}
|
|
211
|
-
catch (error) {
|
|
212
|
-
console.error(`[SignalR] Failed to leave group: ${appObjectId}`, error);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Rejoin all active groups after reconnection
|
|
217
|
-
* This ensures components continue receiving notifications after network interruption
|
|
218
|
-
*/
|
|
219
|
-
async rejoinGroups() {
|
|
220
|
-
if (this.activeGroups.size === 0) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
// Get list of groups to rejoin
|
|
224
|
-
const groups = Array.from(this.activeGroups);
|
|
225
|
-
// Clear the set (will be re-added during joinGroup)
|
|
226
|
-
this.activeGroups.clear();
|
|
227
|
-
// Rejoin each group
|
|
228
|
-
for (const appObjectId of groups) {
|
|
229
|
-
await this.joinGroup(appObjectId);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Check if connected
|
|
234
|
-
*/
|
|
235
|
-
isConnected() {
|
|
236
|
-
return this.hubConnection?.state === signalR.HubConnectionState.Connected;
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Disconnect from SignalR hub (cleanup)
|
|
240
|
-
*/
|
|
241
|
-
async disconnect() {
|
|
242
|
-
if (this.hubConnection) {
|
|
243
|
-
try {
|
|
244
|
-
await this.hubConnection.stop();
|
|
245
|
-
this.hubConnection = null;
|
|
246
|
-
this.connectionState.set(CONNECTION_STATE.DISCONNECTED);
|
|
247
|
-
}
|
|
248
|
-
catch (error) {
|
|
249
|
-
console.error('[SignalR] Error during disconnect:', error);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Get active groups (for debugging)
|
|
255
|
-
*/
|
|
256
|
-
getActiveGroups() {
|
|
257
|
-
return Array.from(this.activeGroups);
|
|
258
|
-
}
|
|
259
|
-
static { this.ɵfac = function SignalRInfrastructure_Factory(t) { return new (t || SignalRInfrastructure)(); }; }
|
|
260
|
-
static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: SignalRInfrastructure, factory: SignalRInfrastructure.ɵfac, providedIn: 'root' }); }
|
|
261
|
-
}
|
|
262
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SignalRInfrastructure, [{
|
|
263
|
-
type: Injectable,
|
|
264
|
-
args: [{
|
|
265
|
-
providedIn: 'root',
|
|
266
|
-
}]
|
|
267
|
-
}], null, null); })();
|
|
268
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9kYXRhLWFjY2Vzcy9zcmMvbGliL3RhYi1jb3JlLXV0aWxpdHkvY29yZS9zZXJ2aWNlL3NpZ25hbHIvc2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEtBQUssT0FBTyxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3ZELE9BQU8sRUFJTCxtQkFBbUIsRUFDbkIsY0FBYyxFQUNkLGNBQWMsRUFDZCxnQkFBZ0IsR0FDakIsTUFBTSwyQ0FBMkMsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUM1RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQzs7QUFFMUU7Ozs7R0FJRztBQUlILE1BQU0sT0FBTyxxQkFBcUI7SUFIbEM7UUFJVSxrQkFBYSxHQUFpQyxJQUFJLENBQUM7UUFFM0Qsa0JBQWtCO1FBQ1QsMEJBQXFCLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFFL0QsZ0JBQWdCO1FBQ1Asd0JBQW1CLEdBQUcsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFFM0QsNkJBQTZCO1FBQ3BCLG9CQUFlLEdBQUcsTUFBTSxDQUFrQixnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVsRiwyREFBMkQ7UUFDbEQs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SCxXQUFXO1FBQ1QsT0FBTyxJQUFJLENBQUMsYUFBYSxFQUFFLEtBQUssS0FBSyxPQUFPLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDO0lBQzVFLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxVQUFVO1FBQ2QsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDaEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7Z0JBQzFCLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzFELENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsb0NBQW9DLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDN0QsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxlQUFlO1FBQ2IsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN2QyxDQUFDO3NGQXpTVSxxQkFBcUI7dUVBQXJCLHFCQUFxQixXQUFyQixxQkFBcUIsbUJBRnBCLE1BQU07O2lGQUVQLHFCQUFxQjtjQUhqQyxVQUFVO2VBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QsIEluamVjdGFibGUsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgKiBhcyBzaWduYWxSIGZyb20gJ0BtaWNyb3NvZnQvc2lnbmFscic7XHJcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgQ29tbW9uIH0gZnJvbSAnLi4vLi4vLi4vYXBwL2NvbnN0YW50cy9jb21tb24nO1xyXG5pbXBvcnQge1xyXG4gIENvbm5lY3Rpb25TdGF0ZSxcclxuICBDcnVkTm90aWZpY2F0aW9uLFxyXG4gIFNpZ25hbFJNZXNzYWdlLFxyXG4gIFNJR05BTFJfSFVCX01FVEhPRFMsXHJcbiAgU0lHTkFMUl9FVkVOVFMsXHJcbiAgQ1JVRF9PUEVSQVRJT04sXHJcbiAgQ09OTkVDVElPTl9TVEFURSxcclxufSBmcm9tICcuLi8uLi8uLi9hcHAvaW50ZXJmYWNlcy9zaWduYWxyLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IFN0b3JhZ2VDb25zdGFudHMgfSBmcm9tICcuLi8uLi8uLi9hcHAvY29uc3RhbnRzL3N0b3JhZ2UtY29uc3RhbnRzJztcclxuaW1wb3J0IHsgU2Vzc2lvblN0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vYXV0aC9zZXNzaW9uLXN0b3JhZ2Uuc2VydmljZSc7XHJcbmltcG9ydCB7IExvY2FsU3RvcmFnZVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9hdXRoL2xvY2FsLXN0b3JhZ2Uuc2VydmljZSc7XHJcblxyXG4vKipcclxuICogU2lnbmFsUiBJbmZyYXN0cnVjdHVyZSBTZXJ2aWNlXHJcbiAqIEhhbmRsZXMgbG93LWxldmVsIFdlYlNvY2tldCBjb25uZWN0aW9uLCBncm91cCBtYW5hZ2VtZW50LCBhbmQgcmVjb25uZWN0aW9uXHJcbiAqIEludGVybmFsIHVzZSBvbmx5IC0gY29tcG9uZW50cyBzaG91bGQgdXNlIFNpZ25hbFJTZXJ2aWNlIGluc3RlYWRcclxuICovXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCcsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTaWduYWxSSW5mcmFzdHJ1Y3R1cmUge1xyXG4gIHByaXZhdGUgaHViQ29ubmVjdGlvbjogc2lnbmFsUi5IdWJDb25uZWN0aW9uIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIC8vIFNlc3Npb24gc3RvcmFnZVxyXG4gIHJlYWRvbmx5IHNlc3Npb25TdG9yYWdlU2VydmljZSA9IGluamVjdChTZXNzaW9uU3RvcmFnZVNlcnZpY2UpO1xyXG5cclxuICAvLyBsb2NhbCBzdG9yYWdlXHJcbiAgcmVhZG9ubHkgbG9jYWxTdG9yYWdlU2VydmljZSA9IGluamVjdChMb2NhbFN0b3JhZ2VTZXJ2aWNlKTtcclxuXHJcbiAgLy8gQ29ubmVjdGlvbiBzdGF0ZSBhcyBzaWduYWxcclxuICByZWFkb25seSBjb25uZWN0aW9uU3RhdGUgPSBzaWduYWw8Q29ubmVjdGlvblN0YXRlPihDT05ORUNUSU9OX1NUQVRFLkRJU0NPTk5FQ1RFRCk7XHJcblxyXG4gIC8vIE5vdGlmaWNhdGlvbiBzdHJlYW0gKGludGVybmFsIC0gZW1pdHMgdG8gU2lnbmFsUlNlcnZpY2UpXHJcbiAgcmVhZG9ubHkgbm90aWZpY2F0aW9ucyQgPSBuZXcgU3ViamVjdDxDcnVkTm90aWZpY2F0aW9uPigpO1xyXG5cclxuICAvLyBUcmFjayBhY3RpdmUgZ3JvdXBzIHRvIHJlam9pbiBhZnRlciByZWNvbm5lY3Rpb25cclxuICBwcml2YXRlIGFjdGl2ZUdyb3VwcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xyXG5cclxuICAvKipcclxuICAgKiBIZWxwZXIgbWV0aG9kIHRvIGdldCB2YWx1ZSBmcm9tIHN0b3JhZ2VcclxuICAgKiBAcGFyYW0gdHlwZSBUaGUgdHlwZSBvZiBzdG9yYWdlLCAnU2Vzc2lvbicgb3IgJ0xvY2FsJ1xyXG4gICAqIEBwYXJhbSBrZXkgVGhlIGtleSB0byByZXRyaWV2ZSB0aGUgdmFsdWUgZm9yXHJcbiAgICogQHJldHVybnMgVGhlIHZhbHVlIGZyb20gc3RvcmFnZSwgb3IgbnVsbCBpZiBub3QgYXZhaWxhYmxlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRGcm9tU3RvcmFnZSh0eXBlOiBzdHJpbmcsIGtleTogc3RyaW5nKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICBsZXQgaW5mbzogYW55ID0gbnVsbDtcclxuXHJcbiAgICAgIGlmICh0eXBlID09PSAnU2Vzc2lvbicpIHtcclxuICAgICAgICAvLyBHZXQgdmFsdWUgZnJvbSBzZXNzaW9uIHN0b3JhZ2VcclxuICAgICAgICBpbmZvID0gdGhpcy5zZXNzaW9uU3RvcmFnZVNlcnZpY2UuZ2V0U2Vzc2lvblN0b3JhZ2Uoa2V5KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHR5cGUgPT09ICdMb2NhbCcpIHtcclxuICAgICAgICAvLyBHZXQgdmFsdWUgZnJvbSBsb2NhbCBzdG9yYWdlXHJcbiAgICAgICAgaW5mbyA9IHRoaXMubG9jYWxTdG9yYWdlU2VydmljZS5nZXRMb2NhbFN0b3JhZ2Uoa2V5KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKGluZm8gJiYgdHlwZW9mIGluZm8gPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgLy8gUGFyc2UgdGhlIHZhbHVlIGlmIGl0J3MgYSBzdHJpbmdcclxuICAgICAgICBpbmZvID0gSlNPTi5wYXJzZShpbmZvKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGluZm87XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAvLyBMb2cgZXJyb3IgaWYgZmFpbGVkIHRvIGdldCB2YWx1ZSBmcm9tIHN0b3JhZ2VcclxuICAgICAgY29uc29sZS53YXJuKCdGYWlsZWQgdG8gZ2V0IGN1cnJlbnQgYXBwIElEIGZyb20gc2Vzc2lvbjonLCBlcnJvcik7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0IGFwcElkKCk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgYXBwSW5mbyA9IHRoaXMuZ2V0RnJvbVN0b3JhZ2UoJ1Nlc3Npb24nLCBTdG9yYWdlQ29uc3RhbnRzLmFwcEluZm8pO1xyXG4gICAgcmV0dXJuIGFwcEluZm8/LklkIHx8IG51bGw7XHJcbiAgfVxyXG5cclxuICBnZXQgZW52aXJvbm1lbnRJZCgpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IGVudkluZm8gPSB0aGlzLmdldEZyb21TdG9yYWdlKCdTZXNzaW9uJywgU3RvcmFnZUNvbnN0YW50cy5lbnZpcm9ubWVudEluZm8pO1xyXG4gICAgcmV0dXJuIGVudkluZm8/LklkIHx8IG51bGw7XHJcbiAgfVxyXG5cclxuICBnZXQgdGVuYW50SWQoKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICBjb25zdCB0ZW5hbnRJbmZvID0gdGhpcy5nZXRGcm9tU3RvcmFnZSgnTG9jYWwnLCBTdG9yYWdlQ29uc3RhbnRzLm9yZ0luZm8pO1xyXG4gICAgcmV0dXJuIHRlbmFudEluZm8/LklkIHx8IG51bGw7XHJcbiAgfVxyXG5cclxuICBnZXQgdG9rZW4oKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICBjb25zdCBhdXRoSW5mbyA9IHRoaXMuZ2V0RnJvbVN0b3JhZ2UoJ0xvY2FsJywgU3RvcmFnZUNvbnN0YW50cy50b2tlbkluZm8pO1xyXG4gICAgcmV0dXJuIGF1dGhJbmZvPy50b2tlbiB8fCBudWxsO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ29ubmVjdCB0byBTaWduYWxSIGh1YlxyXG4gICAqL1xyXG4gIGFzeW5jIGNvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAodGhpcy5odWJDb25uZWN0aW9uPy5zdGF0ZSA9PT0gc2lnbmFsUi5IdWJDb25uZWN0aW9uU3RhdGUuQ29ubmVjdGVkKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBHZXQgaHViIFVSTCBmcm9tIENvbW1vbiAoc2V0IGR1cmluZyBhcHAgaW5pdGlhbGl6YXRpb24gdmlhIENvbW1vbi5pbml0KCkpXHJcbiAgICBjb25zdCBodWJVcmwgPSBDb21tb24uc2lnbmFsUkh1YlVybDtcclxuXHJcbiAgICBpZiAoIWh1YlVybCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdbU2lnbmFsUl0gSHViIFVSTCBub3QgY29uZmlndXJlZC4gTWFrZSBzdXJlIENvbW1vbi5pbml0KCkgaXMgY2FsbGVkIHdpdGggZW52aXJvbm1lbnQuJyk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5DT05ORUNUSU5HKTtcclxuXHJcbiAgICAgIHRoaXMuaHViQ29ubmVjdGlvbiA9IG5ldyBzaWduYWxSLkh1YkNvbm5lY3Rpb25CdWlsZGVyKClcclxuICAgICAgICAud2l0aFVybChodWJVcmwsIHtcclxuICAgICAgICAgIGFjY2Vzc1Rva2VuRmFjdG9yeTogKCkgPT4gdGhpcy50b2tlbiB8fCAnJyxcclxuICAgICAgICAgIHNraXBOZWdvdGlhdGlvbjogZmFsc2UsXHJcbiAgICAgICAgICB0cmFuc3BvcnQ6IHNpZ25hbFIuSHR0cFRyYW5zcG9ydFR5cGUuV2ViU29ja2V0cyB8IHNpZ25hbFIuSHR0cFRyYW5zcG9ydFR5cGUuU2VydmVyU2VudEV2ZW50cyxcclxuICAgICAgICB9KVxyXG4gICAgICAgIC53aXRoQXV0b21hdGljUmVjb25uZWN0KHtcclxuICAgICAgICAgIG5leHRSZXRyeURlbGF5SW5NaWxsaXNlY29uZHM6IChyZXRyeUNvbnRleHQ6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAvLyBFeHBvbmVudGlhbCBiYWNrb2ZmOiAwcywgMnMsIDEwcywgMzBzLCBtYXggNjBzXHJcbiAgICAgICAgICAgIGlmIChyZXRyeUNvbnRleHQuZWxhcHNlZE1pbGxpc2Vjb25kcyA8IDYwMDAwKSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIE1hdGgubWluKDEwMDAgKiBNYXRoLnBvdygyLCByZXRyeUNvbnRleHQucHJldmlvdXNSZXRyeUNvdW50KSwgNjAwMDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsOyAvLyBTdG9wIHJldHJ5aW5nIGFmdGVyIDEgbWludXRlXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLmNvbmZpZ3VyZUxvZ2dpbmcoc2lnbmFsUi5Mb2dMZXZlbC5JbmZvcm1hdGlvbilcclxuICAgICAgICAuYnVpbGQoKTtcclxuXHJcbiAgICAgIHRoaXMucmVnaXN0ZXJFdmVudEhhbmRsZXJzKCk7XHJcbiAgICAgIHRoaXMucmVnaXN0ZXJDb25uZWN0aW9uTGlmZWN5Y2xlKCk7XHJcblxyXG4gICAgICBhd2FpdCB0aGlzLmh1YkNvbm5lY3Rpb24uc3RhcnQoKTtcclxuXHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5GQUlMRUQpO1xyXG5cclxuICAgICAgLy8gUmV0cnkgYWZ0ZXIgMSBtaW51dGVcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmNvbm5lY3QoKSwgNjAgKiAxMDAwKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlZ2lzdGVyIFNpZ25hbFIgZXZlbnQgaGFuZGxlcnMgZm9yIENSVUQgbm90aWZpY2F0aW9uc1xyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVnaXN0ZXJFdmVudEhhbmRsZXJzKCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLmh1YkNvbm5lY3Rpb24pIHJldHVybjtcclxuXHJcbiAgICAvLyBJTlNFUlQgbm90aWZpY2F0aW9uc1xyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9uKFNJR05BTFJfRVZFTlRTLklOU0VSVF9DT01QTEVURUQsICguLi5hcmdzOiBhbnlbXSkgPT4ge1xyXG4gICAgICBjb25zdCBub3RpZmljYXRpb24gPSB0aGlzLmV4dHJhY3ROb3RpZmljYXRpb24oYXJncyk7XHJcbiAgICAgIGNvbnN0IGVucmljaGVkID0geyAuLi5ub3RpZmljYXRpb24sIG9wZXJhdGlvbjogQ1JVRF9PUEVSQVRJT04uSU5TRVJULCByZWNlaXZlZEF0OiBuZXcgRGF0ZSgpIH07XHJcbiAgICAgIHRoaXMubm90aWZpY2F0aW9ucyQubmV4dChlbnJpY2hlZCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBVUERBVEUgbm90aWZpY2F0aW9uc1xyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9uKFNJR05BTFJfRVZFTlRTLlVQREFURV9DT01QTEVURUQsICguLi5hcmdzOiBhbnlbXSkgPT4ge1xyXG4gICAgICBjb25zdCBub3RpZmljYXRpb24gPSB0aGlzLmV4dHJhY3ROb3RpZmljYXRpb24oYXJncyk7XHJcbiAgICAgIGNvbnN0IGVucmljaGVkID0geyAuLi5ub3RpZmljYXRpb24sIG9wZXJhdGlvbjogQ1JVRF9PUEVSQVRJT04uVVBEQVRFLCByZWNlaXZlZEF0OiBuZXcgRGF0ZSgpIH07XHJcbiAgICAgIHRoaXMubm90aWZpY2F0aW9ucyQubmV4dChlbnJpY2hlZCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBERUxFVEUgbm90aWZpY2F0aW9uc1xyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9uKFNJR05BTFJfRVZFTlRTLkRFTEVURV9DT01QTEVURUQsICguLi5hcmdzOiBhbnlbXSkgPT4ge1xyXG4gICAgICBjb25zdCBub3RpZmljYXRpb24gPSB0aGlzLmV4dHJhY3ROb3RpZmljYXRpb24oYXJncyk7XHJcbiAgICAgIGNvbnN0IGVucmljaGVkID0geyAuLi5ub3RpZmljYXRpb24sIG9wZXJhdGlvbjogQ1JVRF9PUEVSQVRJT04uREVMRVRFLCByZWNlaXZlZEF0OiBuZXcgRGF0ZSgpIH07XHJcbiAgICAgIHRoaXMubm90aWZpY2F0aW9ucyQubmV4dChlbnJpY2hlZCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEV4dHJhY3Qgbm90aWZpY2F0aW9uIGZyb20gU2lnbmFsUiBjYWxsYmFjayBhcmdzXHJcbiAgICogSGFuZGxlcyBib3RoIHVud3JhcHBlZCAoZGlyZWN0IG9iamVjdCkgYW5kIHdyYXBwZWQgKHsgdHlwZSwgdGFyZ2V0LCBhcmd1bWVudHMgfSkgZm9ybWF0c1xyXG4gICAqL1xyXG4gIHByaXZhdGUgZXh0cmFjdE5vdGlmaWNhdGlvbihhcmdzOiBhbnlbXSk6IENydWROb3RpZmljYXRpb24ge1xyXG4gICAgY29uc3QgZGF0YSA9IGFyZ3NbMF07XHJcblxyXG4gICAgLy8gSWYgU2lnbmFsUiBkaWRuJ3QgdW53cmFwOiBkYXRhIGlzIHJhdyBTaWduYWxSTWVzc2FnZSB3aXRoIHsgdHlwZSwgdGFyZ2V0LCBhcmd1bWVudHM6IFsuLi5dIH1cclxuICAgIGlmIChkYXRhPy5hcmd1bWVudHMgJiYgQXJyYXkuaXNBcnJheShkYXRhLmFyZ3VtZW50cykpIHtcclxuICAgICAgcmV0dXJuIChkYXRhIGFzIFNpZ25hbFJNZXNzYWdlKS5hcmd1bWVudHNbMF07XHJcbiAgICB9XHJcblxyXG4gICAgLy8gSWYgU2lnbmFsUiB1bndyYXBwZWQ6IGRhdGEgaXMgdGhlIG5vdGlmaWNhdGlvbiBkaXJlY3RseVxyXG4gICAgcmV0dXJuIGRhdGEgYXMgQ3J1ZE5vdGlmaWNhdGlvbjtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlZ2lzdGVyIGNvbm5lY3Rpb24gbGlmZWN5Y2xlIGhhbmRsZXJzXHJcbiAgICovXHJcbiAgcHJpdmF0ZSByZWdpc3RlckNvbm5lY3Rpb25MaWZlY3ljbGUoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuaHViQ29ubmVjdGlvbikgcmV0dXJuO1xyXG5cclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbnJlY29ubmVjdGluZygoKSA9PiB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLlJFQ09OTkVDVElORyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmh1YkNvbm5lY3Rpb24ub25yZWNvbm5lY3RlZCgoKSA9PiB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCk7XHJcblxyXG4gICAgICAvLyBSZWpvaW4gYWxsIGdyb3VwcyBhZnRlciByZWNvbm5lY3Rpb25cclxuICAgICAgdGhpcy5yZWpvaW5Hcm91cHMoKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbmNsb3NlKCgpID0+IHtcclxuICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KENPTk5FQ1RJT05fU1RBVEUuRElTQ09OTkVDVEVEKTtcclxuXHJcbiAgICAgIC8vIFRyeSB0byByZWNvbm5lY3RcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmNvbm5lY3QoKSwgNjAgKiAxMDAwKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSm9pbiBTaWduYWxSIGdyb3VwIGZvciBhbiBBcHBPYmplY3RcclxuICAgKi9cclxuICBhc3luYyBqb2luR3JvdXAoYXBwT2JqZWN0SWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgaWYgKCF0aGlzLmh1YkNvbm5lY3Rpb24gfHwgdGhpcy5odWJDb25uZWN0aW9uLnN0YXRlICE9PSBzaWduYWxSLkh1YkNvbm5lY3Rpb25TdGF0ZS5Db25uZWN0ZWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIGlmICghdGhpcy50ZW5hbnRJZCB8fCAhdGhpcy5hcHBJZCB8fCAhdGhpcy5lbnZpcm9ubWVudElkIHx8ICFhcHBPYmplY3RJZCkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgYXdhaXQgdGhpcy5odWJDb25uZWN0aW9uLmludm9rZShcclxuICAgICAgICBTSUdOQUxSX0hVQl9NRVRIT0RTLkpPSU5fR1JPVVAsXHJcbiAgICAgICAgdGhpcy50ZW5hbnRJZCxcclxuICAgICAgICB0aGlzLmFwcElkLFxyXG4gICAgICAgIHRoaXMuZW52aXJvbm1lbnRJZCxcclxuICAgICAgICBhcHBPYmplY3RJZFxyXG4gICAgICApO1xyXG5cclxuICAgICAgLy8gVHJhY2sgdGhpcyBncm91cCBmb3IgcmVjb25uZWN0aW9uXHJcbiAgICAgIHRoaXMuYWN0aXZlR3JvdXBzLmFkZChhcHBPYmplY3RJZCk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGBbU2lnbmFsUl0gRmFpbGVkIHRvIGpvaW4gZ3JvdXA6ICR7YXBwT2JqZWN0SWR9YCwgZXJyb3IpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTGVhdmUgU2lnbmFsUiBncm91cFxyXG4gICAqL1xyXG4gIGFzeW5jIGxlYXZlR3JvdXAoYXBwT2JqZWN0SWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgaWYgKCF0aGlzLmh1YkNvbm5lY3Rpb24gfHwgdGhpcy5odWJDb25uZWN0aW9uLnN0YXRlICE9PSBzaWduYWxSLkh1YkNvbm5lY3Rpb25TdGF0ZS5Db25uZWN0ZWQpIHtcclxuICAgICAgLy8gUmVtb3ZlIGZyb20gdHJhY2tpbmcgZXZlbiBpZiBub3QgY29ubmVjdGVkXHJcbiAgICAgIHRoaXMuYWN0aXZlR3JvdXBzLmRlbGV0ZShhcHBPYmplY3RJZCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMudGVuYW50SWQgfHwgIXRoaXMuYXBwSWQgfHwgIXRoaXMuZW52aXJvbm1lbnRJZCB8fCAhYXBwT2JqZWN0SWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIGF3YWl0IHRoaXMuaHViQ29ubmVjdGlvbi5pbnZva2UoXHJcbiAgICAgICAgU0lHTkFMUl9IVUJfTUVUSE9EUy5MRUFWRV9HUk9VUCxcclxuICAgICAgICB0aGlzLnRlbmFudElkLFxyXG4gICAgICAgIHRoaXMuYXBwSWQsXHJcbiAgICAgICAgdGhpcy5lbnZpcm9ubWVudElkLFxyXG4gICAgICAgIGFwcE9iamVjdElkXHJcbiAgICAgICk7XHJcblxyXG4gICAgICAvLyBSZW1vdmUgZnJvbSB0cmFja2luZ1xyXG4gICAgICB0aGlzLmFjdGl2ZUdyb3Vwcy5kZWxldGUoYXBwT2JqZWN0SWQpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgY29uc29sZS5lcnJvcihgW1NpZ25hbFJdIEZhaWxlZCB0byBsZWF2ZSBncm91cDogJHthcHBPYmplY3RJZH1gLCBlcnJvcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWpvaW4gYWxsIGFjdGl2ZSBncm91cHMgYWZ0ZXIgcmVjb25uZWN0aW9uXHJcbiAgICogVGhpcyBlbnN1cmVzIGNvbXBvbmVudHMgY29udGludWUgcmVjZWl2aW5nIG5vdGlmaWNhdGlvbnMgYWZ0ZXIgbmV0d29yayBpbnRlcnJ1cHRpb25cclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIHJlam9pbkdyb3VwcygpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICh0aGlzLmFjdGl2ZUdyb3Vwcy5zaXplID09PSAwKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBHZXQgbGlzdCBvZiBncm91cHMgdG8gcmVqb2luXHJcbiAgICBjb25zdCBncm91cHMgPSBBcnJheS5mcm9tKHRoaXMuYWN0aXZlR3JvdXBzKTtcclxuXHJcbiAgICAvLyBDbGVhciB0aGUgc2V0ICh3aWxsIGJlIHJlLWFkZGVkIGR1cmluZyBqb2luR3JvdXApXHJcbiAgICB0aGlzLmFjdGl2ZUdyb3Vwcy5jbGVhcigpO1xyXG5cclxuICAgIC8vIFJlam9pbiBlYWNoIGdyb3VwXHJcbiAgICBmb3IgKGNvbnN0IGFwcE9iamVjdElkIG9mIGdyb3Vwcykge1xyXG4gICAgICBhd2FpdCB0aGlzLmpvaW5Hcm91cChhcHBPYmplY3RJZCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGVjayBpZiBjb25uZWN0ZWRcclxuICAgKi9cclxuICBpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmh1YkNvbm5lY3Rpb24/LnN0YXRlID09PSBzaWduYWxSLkh1YkNvbm5lY3Rpb25TdGF0ZS5Db25uZWN0ZWQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBEaXNjb25uZWN0IGZyb20gU2lnbmFsUiBodWIgKGNsZWFudXApXHJcbiAgICovXHJcbiAgYXN5bmMgZGlzY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICh0aGlzLmh1YkNvbm5lY3Rpb24pIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBhd2FpdCB0aGlzLmh1YkNvbm5lY3Rpb24uc3RvcCgpO1xyXG4gICAgICAgIHRoaXMuaHViQ29ubmVjdGlvbiA9IG51bGw7XHJcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KENPTk5FQ1RJT05fU1RBVEUuRElTQ09OTkVDVEVEKTtcclxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKCdbU2lnbmFsUl0gRXJyb3IgZHVyaW5nIGRpc2Nvbm5lY3Q6JywgZXJyb3IpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgYWN0aXZlIGdyb3VwcyAoZm9yIGRlYnVnZ2luZylcclxuICAgKi9cclxuICBnZXRBY3RpdmVHcm91cHMoKTogc3RyaW5nW10ge1xyXG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5hY3RpdmVHcm91cHMpO1xyXG4gIH1cclxufSJdfQ==
|
|
@@ -1,207 +0,0 @@
|
|
|
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=
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { CommonApiResponse, StandardApiResponse } from '../interfaces/common.interface';
|
|
2
|
-
/**
|
|
3
|
-
* ResponseAdapter - Transforms new API response format to legacy format
|
|
4
|
-
*
|
|
5
|
-
* This adapter maintains backward compatibility by converting the new camelCase
|
|
6
|
-
* response format from the backend to the old PascalCase format expected by
|
|
7
|
-
* existing application code.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* // Auto-detect and normalize response
|
|
11
|
-
* return this.apiService.postToService(...).pipe(
|
|
12
|
-
* map(response => ResponseAdapter.normalize(response))
|
|
13
|
-
* );
|
|
14
|
-
*/
|
|
15
|
-
export declare class ResponseAdapter {
|
|
16
|
-
/**
|
|
17
|
-
* Normalizes a StandardApiResponse to CommonApiResponse format.
|
|
18
|
-
* @param newResponse The response object in the new API format.
|
|
19
|
-
* @returns The normalized response in the legacy format.
|
|
20
|
-
*/
|
|
21
|
-
static normalize(newResponse: StandardApiResponse): CommonApiResponse;
|
|
22
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Raw SignalR message wrapper
|
|
3
|
-
*/
|
|
4
|
-
export interface SignalRMessage {
|
|
5
|
-
type: number;
|
|
6
|
-
target: string;
|
|
7
|
-
arguments: CrudNotification[];
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* CRUD notification payload received from SignalR hub
|
|
11
|
-
*/
|
|
12
|
-
export interface CrudNotification {
|
|
13
|
-
correlationId: string;
|
|
14
|
-
result: any;
|
|
15
|
-
entityName: string;
|
|
16
|
-
appObjectId: string;
|
|
17
|
-
isSuccess: boolean;
|
|
18
|
-
errorMessage: string | null;
|
|
19
|
-
errorCode: string | null;
|
|
20
|
-
executionTimeMs: number;
|
|
21
|
-
affectedRecords: number | null;
|
|
22
|
-
operation?: CrudOperation;
|
|
23
|
-
receivedAt?: Date;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Pending async operation tracked by OperationTrackerService
|
|
27
|
-
*/
|
|
28
|
-
export interface PendingOperation {
|
|
29
|
-
correlationId: string;
|
|
30
|
-
timestamp: Date;
|
|
31
|
-
timeout: number;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Callback function type for component notifications
|
|
35
|
-
*/
|
|
36
|
-
export type NotificationCallback = (notification: CrudNotification) => void;
|
|
37
|
-
/**
|
|
38
|
-
* CRUD operation types
|
|
39
|
-
*/
|
|
40
|
-
export type CrudOperation = typeof CRUD_OPERATION[keyof typeof CRUD_OPERATION];
|
|
41
|
-
/**
|
|
42
|
-
* SignalR connection state types
|
|
43
|
-
*/
|
|
44
|
-
export type ConnectionState = typeof CONNECTION_STATE[keyof typeof CONNECTION_STATE];
|
|
45
|
-
/**
|
|
46
|
-
* SignalR hub method names
|
|
47
|
-
*/
|
|
48
|
-
export declare const SIGNALR_HUB_METHODS: {
|
|
49
|
-
readonly JOIN_GROUP: "JoinGroupAsync";
|
|
50
|
-
readonly LEAVE_GROUP: "LeaveGroupAsync";
|
|
51
|
-
};
|
|
52
|
-
/**
|
|
53
|
-
* SignalR event names from backend
|
|
54
|
-
*/
|
|
55
|
-
export declare const SIGNALR_EVENTS: {
|
|
56
|
-
readonly INSERT_COMPLETED: "InsertOperationCompleted";
|
|
57
|
-
readonly UPDATE_COMPLETED: "UpdateOperationCompleted";
|
|
58
|
-
readonly DELETE_COMPLETED: "DeleteOperationCompleted";
|
|
59
|
-
};
|
|
60
|
-
/**
|
|
61
|
-
* CRUD operation types
|
|
62
|
-
*/
|
|
63
|
-
export declare const CRUD_OPERATION: {
|
|
64
|
-
readonly INSERT: "INSERT";
|
|
65
|
-
readonly UPDATE: "UPDATE";
|
|
66
|
-
readonly DELETE: "DELETE";
|
|
67
|
-
};
|
|
68
|
-
/**
|
|
69
|
-
* SignalR connection states
|
|
70
|
-
*/
|
|
71
|
-
export declare const CONNECTION_STATE: {
|
|
72
|
-
readonly DISCONNECTED: "Disconnected";
|
|
73
|
-
readonly CONNECTING: "Connecting";
|
|
74
|
-
readonly CONNECTED: "Connected";
|
|
75
|
-
readonly RECONNECTING: "Reconnecting";
|
|
76
|
-
readonly FAILED: "Failed";
|
|
77
|
-
};
|
|
78
|
-
/**
|
|
79
|
-
* SignalR configuration constants
|
|
80
|
-
*/
|
|
81
|
-
export declare const SIGNALR_CONFIG: {
|
|
82
|
-
readonly DEFAULT_TIMEOUT: 120000;
|
|
83
|
-
readonly RECONNECT_DELAYS: readonly [0, 2000, 10000, 30000, 60000];
|
|
84
|
-
};
|