@openremote/core 1.0.2 → 1.2.0-snapshot.20240512154942
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/README.md +86 -8
- package/lib/asset-mixin.d.ts +46 -0
- package/lib/asset-mixin.js +1 -0
- package/lib/asset-mixin.js.map +1 -0
- package/{dist → lib}/console.d.ts +21 -12
- package/lib/console.js +1 -0
- package/lib/console.js.map +1 -0
- package/lib/defaults.d.ts +15 -0
- package/lib/defaults.js +1 -0
- package/lib/defaults.js.map +1 -0
- package/{dist → lib}/event.d.ts +30 -16
- package/lib/event.js +1 -0
- package/lib/event.js.map +1 -0
- package/lib/index.d.ts +150 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -0
- package/lib/util.d.ts +92 -0
- package/lib/util.js +1 -0
- package/lib/util.js.map +1 -0
- package/package.json +31 -14
- package/dist/asset-mixin.d.ts +0 -25
- package/dist/asset-mixin.js +0 -115
- package/dist/asset-mixin.js.map +0 -1
- package/dist/console.js +0 -446
- package/dist/console.js.map +0 -1
- package/dist/event.js +0 -454
- package/dist/event.js.map +0 -1
- package/dist/index.d.ts +0 -137
- package/dist/index.js +0 -683
- package/dist/index.js.map +0 -1
- package/dist/util.d.ts +0 -17
- package/dist/util.js +0 -72
- package/dist/util.js.map +0 -1
- package/src/asset-mixin.ts +0 -132
- package/src/console.d.ts +0 -56
- package/src/console.js +0 -451
- package/src/console.js.map +0 -1
- package/src/console.ts +0 -530
- package/src/event.d.ts +0 -75
- package/src/event.js +0 -410
- package/src/event.js.map +0 -1
- package/src/event.ts +0 -584
- package/src/index.d.ts +0 -110
- package/src/index.js +0 -525
- package/src/index.js.map +0 -1
- package/src/index.ts +0 -803
- package/src/util.d.ts +0 -15
- package/src/util.js +0 -46
- package/src/util.js.map +0 -1
- package/src/util.ts +0 -94
- package/tsconfig.json +0 -14
- package/tsconfig.tsbuildinfo +0 -9788
package/src/event.ts
DELETED
|
@@ -1,584 +0,0 @@
|
|
|
1
|
-
import openremote from "./index";
|
|
2
|
-
import {arrayRemove, Deferred} from "./util";
|
|
3
|
-
import {
|
|
4
|
-
AttributeEvent,
|
|
5
|
-
CancelEventSubscription,
|
|
6
|
-
EventSubscription,
|
|
7
|
-
RenewEventSubscriptions,
|
|
8
|
-
SharedEvent,
|
|
9
|
-
ReadAssetAttributesEvent,
|
|
10
|
-
AssetEvent,
|
|
11
|
-
ReadAssetEvent
|
|
12
|
-
} from "@openremote/model";
|
|
13
|
-
|
|
14
|
-
export enum EventProviderStatus {
|
|
15
|
-
DISCONNECTED = "DISCONNECTED",
|
|
16
|
-
CONNECTED = "CONNECTED",
|
|
17
|
-
CONNECTING = "CONNECTING"
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface EventProvider {
|
|
21
|
-
status: EventProviderStatus;
|
|
22
|
-
|
|
23
|
-
connect(): Promise<boolean>;
|
|
24
|
-
|
|
25
|
-
disconnect(): void;
|
|
26
|
-
|
|
27
|
-
subscribeStatusChange(callback: (status: EventProviderStatus) => void): void;
|
|
28
|
-
|
|
29
|
-
unsubscribeStatusChange(callback: (status: EventProviderStatus) => void): void;
|
|
30
|
-
|
|
31
|
-
subscribe<T extends SharedEvent>(eventSubscription: EventSubscription<T>, callback: (event: T) => void): Promise<string>;
|
|
32
|
-
|
|
33
|
-
unsubscribe<T extends SharedEvent>(subscriptionId: string): void;
|
|
34
|
-
|
|
35
|
-
subscribeAssetEvents(assetIds: string[] | null, callback: (event: AssetEvent) => void): Promise<string>;
|
|
36
|
-
|
|
37
|
-
subscribeAttributeEvents(assetIds: string[], requestCurrentValues: boolean, callback: (event: AttributeEvent) => void): Promise<string>;
|
|
38
|
-
|
|
39
|
-
sendEvent<T extends SharedEvent>(event: T): void;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Interface to provide a singleton implementation of EventProvider
|
|
43
|
-
export interface EventProviderFactory {
|
|
44
|
-
getEventProvider(): EventProvider | undefined;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
interface EventSubscriptionInfo<T extends SharedEvent> {
|
|
48
|
-
eventSubscription: EventSubscription<T>;
|
|
49
|
-
callback: (event: T) => void;
|
|
50
|
-
deferred: Deferred<string> | null;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const SUBSCRIBE_MESSAGE_PREFIX = "SUBSCRIBE:";
|
|
54
|
-
const SUBSCRIBED_MESSAGE_PREFIX = "SUBSCRIBED:";
|
|
55
|
-
const UNSUBSCRIBE_MESSAGE_PREFIX = "UNSUBSCRIBE:";
|
|
56
|
-
const RENEW_MESSAGE_PREFIX = "RENEW:";
|
|
57
|
-
const UNAUTHORIZED_MESSAGE_PREFIX = "UNAUTHORIZED:";
|
|
58
|
-
const EVENT_MESSAGE_PREFIX = "EVENT:";
|
|
59
|
-
|
|
60
|
-
abstract class EventProviderImpl implements EventProvider {
|
|
61
|
-
|
|
62
|
-
protected static MIN_RECONNECT_DELAY: number = 0;
|
|
63
|
-
protected static MAX_RECONNECT_DELAY: number = 30000;
|
|
64
|
-
protected _disconnectRequested: boolean = false;
|
|
65
|
-
protected _reconnectDelayMillis: number = WebSocketEventProvider.MIN_RECONNECT_DELAY;
|
|
66
|
-
protected _reconnectTimer: number | null = null;
|
|
67
|
-
protected _status: EventProviderStatus = EventProviderStatus.DISCONNECTED;
|
|
68
|
-
protected _connectingDeferred: Deferred<boolean> | null = null;
|
|
69
|
-
protected _statusCallbacks: Array<(status: EventProviderStatus) => void> = [];
|
|
70
|
-
protected _pendingSubscription: EventSubscriptionInfo<SharedEvent> | null = null;
|
|
71
|
-
protected _queuedSubscriptions: EventSubscriptionInfo<SharedEvent>[] = [];
|
|
72
|
-
protected _subscriptionMap: { [id: string]: EventSubscriptionInfo<SharedEvent> } = {};
|
|
73
|
-
|
|
74
|
-
abstract get endpointUrl(): string;
|
|
75
|
-
|
|
76
|
-
public get status(): EventProviderStatus {
|
|
77
|
-
return this._status;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
public subscribeStatusChange(callback: (status: EventProviderStatus) => void): void {
|
|
81
|
-
this._statusCallbacks.push(callback);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
public unsubscribeStatusChange(callback: (status: EventProviderStatus) => void): void {
|
|
85
|
-
arrayRemove(this._statusCallbacks, callback);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
public connect(): Promise<boolean> {
|
|
89
|
-
if (this._status === EventProviderStatus.CONNECTED) {
|
|
90
|
-
return Promise.resolve(true);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
this._disconnectRequested = false;
|
|
94
|
-
|
|
95
|
-
if (this._connectingDeferred) {
|
|
96
|
-
return this._connectingDeferred.promise;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
this._onStatusChanged(EventProviderStatus.CONNECTING);
|
|
100
|
-
|
|
101
|
-
this._connectingDeferred = new Deferred();
|
|
102
|
-
|
|
103
|
-
this._doConnect().then((connected: boolean) => {
|
|
104
|
-
if (this._connectingDeferred) {
|
|
105
|
-
let deferred = this._connectingDeferred;
|
|
106
|
-
this._connectingDeferred = null;
|
|
107
|
-
|
|
108
|
-
if (this._reconnectTimer) {
|
|
109
|
-
window.clearTimeout(this._reconnectTimer);
|
|
110
|
-
this._reconnectTimer = null;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (connected) {
|
|
114
|
-
console.debug("Connected to event service: " + this.endpointUrl);
|
|
115
|
-
this._reconnectDelayMillis = WebSocketEventProvider.MIN_RECONNECT_DELAY;
|
|
116
|
-
this._onStatusChanged(EventProviderStatus.CONNECTED);
|
|
117
|
-
|
|
118
|
-
window.setTimeout(() => {
|
|
119
|
-
this._onConnect();
|
|
120
|
-
}, 0);
|
|
121
|
-
} else {
|
|
122
|
-
console.debug("Failed to connect to event service: " + this.endpointUrl);
|
|
123
|
-
this._onStatusChanged(EventProviderStatus.DISCONNECTED);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
deferred.resolve(connected);
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
return this._connectingDeferred.promise;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
public disconnect(): void {
|
|
134
|
-
if (this._disconnectRequested) {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
this._disconnectRequested = true;
|
|
138
|
-
|
|
139
|
-
if (this._reconnectTimer) {
|
|
140
|
-
window.clearTimeout(this._reconnectTimer);
|
|
141
|
-
this._reconnectTimer = null;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (this.status === EventProviderStatus.DISCONNECTED) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
this._doDisconnect();
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
public subscribe<T extends SharedEvent>(eventSubscription: EventSubscription<T>, callback: (event: T) => void): Promise<string> {
|
|
152
|
-
|
|
153
|
-
let subscriptionInfo = {
|
|
154
|
-
eventSubscription: eventSubscription,
|
|
155
|
-
callback: callback as ((event: SharedEvent) => void),
|
|
156
|
-
deferred: new Deferred<string>()
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
if (this._pendingSubscription != null || this._status !== EventProviderStatus.CONNECTED) {
|
|
160
|
-
this._queuedSubscriptions.push(subscriptionInfo);
|
|
161
|
-
return subscriptionInfo.deferred.promise;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
this._pendingSubscription = subscriptionInfo;
|
|
165
|
-
|
|
166
|
-
this._doSubscribe(eventSubscription).then(
|
|
167
|
-
subscriptionId => {
|
|
168
|
-
if (this._pendingSubscription) {
|
|
169
|
-
let subscriptionInfo = this._pendingSubscription;
|
|
170
|
-
this._pendingSubscription = null;
|
|
171
|
-
|
|
172
|
-
// Store subscriptionId and callback
|
|
173
|
-
this._subscriptionMap[subscriptionId] = subscriptionInfo;
|
|
174
|
-
|
|
175
|
-
this._processNextSubscription();
|
|
176
|
-
let deferred = subscriptionInfo.deferred;
|
|
177
|
-
subscriptionInfo.deferred = null;
|
|
178
|
-
|
|
179
|
-
if (deferred) {
|
|
180
|
-
deferred.resolve(subscriptionId);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
},
|
|
184
|
-
reason => {
|
|
185
|
-
if (this._pendingSubscription) {
|
|
186
|
-
let subscriptionInfo = this._pendingSubscription;
|
|
187
|
-
this._pendingSubscription = null;
|
|
188
|
-
this._processNextSubscription();
|
|
189
|
-
let deferred = subscriptionInfo.deferred;
|
|
190
|
-
subscriptionInfo.deferred = null;
|
|
191
|
-
|
|
192
|
-
if (deferred) {
|
|
193
|
-
deferred.reject(reason);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
return this._pendingSubscription.deferred!.promise;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
public unsubscribe<T extends SharedEvent>(subscriptionId: string) {
|
|
202
|
-
|
|
203
|
-
let callback = this._subscriptionMap[subscriptionId];
|
|
204
|
-
if (callback) {
|
|
205
|
-
delete this._subscriptionMap[subscriptionId];
|
|
206
|
-
this._doUnsubscribe(subscriptionId);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
public sendEvent<T extends SharedEvent>(event: T): void {
|
|
211
|
-
this._doSend(event);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
public async subscribeAssetEvents(assetIds: string[] | null, callback: (event: AssetEvent) => void): Promise<string> {
|
|
215
|
-
let subscription: EventSubscription<AssetEvent> = {
|
|
216
|
-
eventType: "asset"
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
if (assetIds && assetIds.length > 0) {
|
|
220
|
-
subscription.filter = {
|
|
221
|
-
filterType: "asset-id",
|
|
222
|
-
assetIds: assetIds
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
let subscriptionId: string | null = null;
|
|
227
|
-
|
|
228
|
-
try {
|
|
229
|
-
subscriptionId = await this.subscribe(subscription, callback);
|
|
230
|
-
|
|
231
|
-
// Get the current state of each asset
|
|
232
|
-
if (assetIds) {
|
|
233
|
-
assetIds.forEach(assetId => {
|
|
234
|
-
let readEvent: ReadAssetEvent = {
|
|
235
|
-
assetId: assetId,
|
|
236
|
-
eventType: "read-asset",
|
|
237
|
-
subscriptionId: subscriptionId!
|
|
238
|
-
};
|
|
239
|
-
this.sendEvent(readEvent);
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
} catch (e) {
|
|
243
|
-
console.error("Failed to subscribe to asset events for assets: " + assetIds);
|
|
244
|
-
if (subscriptionId) {
|
|
245
|
-
this.unsubscribe(subscriptionId);
|
|
246
|
-
}
|
|
247
|
-
throw e;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
return subscriptionId!;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
public async subscribeAttributeEvents(assetIds: string[], requestCurrentValues: boolean, callback: (event: AttributeEvent) => void): Promise<string> {
|
|
254
|
-
let subscription: EventSubscription<AttributeEvent> = {
|
|
255
|
-
eventType: "attribute",
|
|
256
|
-
filter: {
|
|
257
|
-
filterType: "asset-id",
|
|
258
|
-
assetIds: assetIds
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
let subscriptionId: string | null = null;
|
|
263
|
-
|
|
264
|
-
try {
|
|
265
|
-
subscriptionId = await this.subscribe(subscription, callback);
|
|
266
|
-
|
|
267
|
-
// Get the current value of each assets attributes
|
|
268
|
-
if (requestCurrentValues) {
|
|
269
|
-
assetIds.forEach(assetId => {
|
|
270
|
-
let readEvent: ReadAssetAttributesEvent = {
|
|
271
|
-
assetId: assetId,
|
|
272
|
-
eventType: "read-asset-attributes",
|
|
273
|
-
subscriptionId: subscriptionId!
|
|
274
|
-
};
|
|
275
|
-
this.sendEvent(readEvent);
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
} catch (e) {
|
|
279
|
-
console.error("Failed to subscribe to attribute events for assets: " + assetIds);
|
|
280
|
-
if (subscriptionId) {
|
|
281
|
-
this.unsubscribe(subscriptionId);
|
|
282
|
-
}
|
|
283
|
-
throw e;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
return subscriptionId!;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
protected _processNextSubscription() {
|
|
290
|
-
if (this._status !== EventProviderStatus.CONNECTED || this._queuedSubscriptions.length === 0) {
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
setTimeout(() => {
|
|
295
|
-
let subscriptionInfo = this._queuedSubscriptions.shift();
|
|
296
|
-
if (subscriptionInfo) {
|
|
297
|
-
this.subscribe(subscriptionInfo.eventSubscription, subscriptionInfo.callback)
|
|
298
|
-
.then(
|
|
299
|
-
(id: string) => {
|
|
300
|
-
let deferred = subscriptionInfo!.deferred;
|
|
301
|
-
subscriptionInfo!.deferred = null;
|
|
302
|
-
|
|
303
|
-
if (deferred) {
|
|
304
|
-
deferred.resolve(id);
|
|
305
|
-
}
|
|
306
|
-
}, reason => {
|
|
307
|
-
let deferred = subscriptionInfo!.deferred;
|
|
308
|
-
subscriptionInfo!.deferred = null;
|
|
309
|
-
|
|
310
|
-
if (deferred) {
|
|
311
|
-
deferred.reject(reason);
|
|
312
|
-
}
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
}, 0);
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
private _onStatusChanged(status: EventProviderStatus) {
|
|
319
|
-
if (status === this._status) {
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
console.debug("Event provider status changed: " + status);
|
|
324
|
-
|
|
325
|
-
this._status = status;
|
|
326
|
-
window.setTimeout(() => {
|
|
327
|
-
this._statusCallbacks.forEach((cb) => cb(status));
|
|
328
|
-
}, 0);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
protected _onMessageReceived(subscriptionId: string, event: SharedEvent) {
|
|
332
|
-
let subscriptionInfo = this._subscriptionMap[subscriptionId];
|
|
333
|
-
|
|
334
|
-
if (subscriptionInfo) {
|
|
335
|
-
subscriptionInfo.callback(event);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
protected _onConnect() {
|
|
340
|
-
console.debug("Event provider connected: " + this.constructor.name);
|
|
341
|
-
|
|
342
|
-
if (Object.keys(this._subscriptionMap).length > 0) {
|
|
343
|
-
for (const subscriptionId in this._subscriptionMap) {
|
|
344
|
-
if (this._subscriptionMap.hasOwnProperty(subscriptionId)) {
|
|
345
|
-
this._queuedSubscriptions.unshift(this._subscriptionMap[subscriptionId]);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
this._subscriptionMap = {};
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
this._processNextSubscription();
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
protected _onDisconnect() {
|
|
355
|
-
console.debug("Event provider disconnected");
|
|
356
|
-
this._onStatusChanged(EventProviderStatus.DISCONNECTED);
|
|
357
|
-
if (this._pendingSubscription) {
|
|
358
|
-
this._queuedSubscriptions.unshift(this._pendingSubscription);
|
|
359
|
-
this._pendingSubscription = null;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
this._scheduleReconnect();
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
protected _scheduleReconnect() {
|
|
366
|
-
if (this._reconnectTimer) {
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
if (this._disconnectRequested) {
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
console.debug("Event provider scheduling reconnect in " + this._reconnectDelayMillis + "ms");
|
|
375
|
-
|
|
376
|
-
this._reconnectTimer = window.setTimeout(() => {
|
|
377
|
-
|
|
378
|
-
if (this._disconnectRequested) {
|
|
379
|
-
return;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
this.connect().then(connected => {
|
|
383
|
-
if (!connected) {
|
|
384
|
-
this._scheduleReconnect();
|
|
385
|
-
}
|
|
386
|
-
}).catch(error => {
|
|
387
|
-
this._scheduleReconnect();
|
|
388
|
-
});
|
|
389
|
-
}, this._reconnectDelayMillis);
|
|
390
|
-
|
|
391
|
-
if (this._reconnectDelayMillis < WebSocketEventProvider.MAX_RECONNECT_DELAY) {
|
|
392
|
-
this._reconnectDelayMillis = Math.min(WebSocketEventProvider.MAX_RECONNECT_DELAY, this._reconnectDelayMillis + 3000);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
protected abstract _doSend<T extends SharedEvent>(event: T): void;
|
|
397
|
-
|
|
398
|
-
protected abstract _doConnect(): Promise<boolean>;
|
|
399
|
-
|
|
400
|
-
protected abstract _doDisconnect(): void;
|
|
401
|
-
|
|
402
|
-
protected abstract _doSubscribe<T extends SharedEvent>(subscription: EventSubscription<T>): Promise<string>;
|
|
403
|
-
|
|
404
|
-
protected abstract _doUnsubscribe(subscriptionId: string): void;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
export class WebSocketEventProvider extends EventProviderImpl {
|
|
408
|
-
|
|
409
|
-
protected static _subscriptionCounter: number = 1;
|
|
410
|
-
protected static _subscriptionRenewalMillis = 150 * 1000;
|
|
411
|
-
|
|
412
|
-
private readonly _endpointUrl: string;
|
|
413
|
-
protected _webSocket: WebSocket | undefined = undefined;
|
|
414
|
-
protected _connectDeferred: Deferred<boolean> | null = null;
|
|
415
|
-
protected _subscribeDeferred: Deferred<string> | null = null;
|
|
416
|
-
protected _renewalTimer: number | null = null;
|
|
417
|
-
|
|
418
|
-
get endpointUrl(): string {
|
|
419
|
-
return this._endpointUrl;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
constructor(managerUrl: string) {
|
|
423
|
-
super();
|
|
424
|
-
|
|
425
|
-
this._endpointUrl = (managerUrl.startsWith("https:") ? "wss" : "ws") + "://" + managerUrl.substr(managerUrl.indexOf("://") + 3) + "/websocket/events";
|
|
426
|
-
|
|
427
|
-
// Close socket on unload/refresh of page
|
|
428
|
-
window.addEventListener("beforeunload", () => {
|
|
429
|
-
this.disconnect();
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
protected _doConnect(): Promise<boolean> {
|
|
434
|
-
let authorisedUrl = this._endpointUrl + "?Auth-Realm=" + openremote.config.realm;
|
|
435
|
-
|
|
436
|
-
if (openremote.authenticated) {
|
|
437
|
-
authorisedUrl += "&Authorization=" + openremote.getAuthorizationHeader();
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
this._webSocket = new WebSocket(authorisedUrl);
|
|
441
|
-
this._connectDeferred = new Deferred();
|
|
442
|
-
|
|
443
|
-
this._webSocket!.onopen = () => {
|
|
444
|
-
if (this._connectDeferred) {
|
|
445
|
-
let deferred = this._connectDeferred;
|
|
446
|
-
this._connectDeferred = null;
|
|
447
|
-
deferred.resolve(true);
|
|
448
|
-
}
|
|
449
|
-
};
|
|
450
|
-
|
|
451
|
-
this._webSocket!.onerror = () => {
|
|
452
|
-
if (this._connectDeferred) {
|
|
453
|
-
let deferred = this._connectDeferred;
|
|
454
|
-
this._connectDeferred = null;
|
|
455
|
-
deferred.resolve(false);
|
|
456
|
-
} else {
|
|
457
|
-
console.debug("Event provider error");
|
|
458
|
-
// Could have inconsistent state so disconnect and let consumers decide what to do and when to reconnect
|
|
459
|
-
this._beforeDisconnect();
|
|
460
|
-
}
|
|
461
|
-
};
|
|
462
|
-
|
|
463
|
-
this._webSocket!.onclose = () => {
|
|
464
|
-
this._webSocket = undefined;
|
|
465
|
-
|
|
466
|
-
if (this._connectDeferred) {
|
|
467
|
-
let deferred = this._connectDeferred;
|
|
468
|
-
this._connectDeferred = null;
|
|
469
|
-
deferred.resolve(false);
|
|
470
|
-
} else {
|
|
471
|
-
this._beforeDisconnect();
|
|
472
|
-
}
|
|
473
|
-
};
|
|
474
|
-
|
|
475
|
-
this._webSocket!.onmessage = (e) => {
|
|
476
|
-
let msg = e.data as string;
|
|
477
|
-
if (msg && msg.startsWith(SUBSCRIBED_MESSAGE_PREFIX)) {
|
|
478
|
-
let jsonStr = msg.substring(SUBSCRIBED_MESSAGE_PREFIX.length);
|
|
479
|
-
let subscription = JSON.parse(jsonStr) as EventSubscription<SharedEvent>;
|
|
480
|
-
|
|
481
|
-
// Create a renewal timer if not done so
|
|
482
|
-
if (!this._renewalTimer) {
|
|
483
|
-
setInterval(() => {
|
|
484
|
-
this._doRenewal();
|
|
485
|
-
}, WebSocketEventProvider._subscriptionRenewalMillis);
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
let deferred = this._subscribeDeferred;
|
|
489
|
-
this._subscribeDeferred = null;
|
|
490
|
-
if (deferred) {
|
|
491
|
-
deferred.resolve(subscription.subscriptionId);
|
|
492
|
-
}
|
|
493
|
-
} else if (msg.startsWith(UNAUTHORIZED_MESSAGE_PREFIX)) {
|
|
494
|
-
let jsonStr = msg.substring(UNAUTHORIZED_MESSAGE_PREFIX.length);
|
|
495
|
-
let subscription = JSON.parse(jsonStr) as EventSubscription<SharedEvent>;
|
|
496
|
-
let deferred = this._subscribeDeferred;
|
|
497
|
-
this._subscribeDeferred = null;
|
|
498
|
-
if (deferred) {
|
|
499
|
-
console.warn("Unauthorized event subscription: " + subscription);
|
|
500
|
-
deferred.reject("Unauthorized");
|
|
501
|
-
}
|
|
502
|
-
} else if (msg.startsWith(EVENT_MESSAGE_PREFIX)) {
|
|
503
|
-
let str = msg.substring(EVENT_MESSAGE_PREFIX.length);
|
|
504
|
-
let seperatorPos = str.indexOf(":");
|
|
505
|
-
if (seperatorPos > 0) {
|
|
506
|
-
let strArr = [str.substring(0, seperatorPos), str.substring(seperatorPos + 1)];
|
|
507
|
-
let subscriptionId = strArr[0];
|
|
508
|
-
let jsonStr = strArr[1];
|
|
509
|
-
if (jsonStr.startsWith("[")) {
|
|
510
|
-
let events = JSON.parse(jsonStr) as SharedEvent[];
|
|
511
|
-
events.forEach(event => {
|
|
512
|
-
this._onMessageReceived(subscriptionId, event);
|
|
513
|
-
});
|
|
514
|
-
} else {
|
|
515
|
-
let event = JSON.parse(jsonStr) as SharedEvent;
|
|
516
|
-
this._onMessageReceived(subscriptionId, event);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
};
|
|
521
|
-
|
|
522
|
-
return this._connectDeferred.promise;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
protected _beforeDisconnect(): void {
|
|
526
|
-
if (this._renewalTimer != null) {
|
|
527
|
-
clearInterval(this._renewalTimer);
|
|
528
|
-
this._renewalTimer = null;
|
|
529
|
-
}
|
|
530
|
-
this._onDisconnect();
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
protected _doDisconnect(): void {
|
|
534
|
-
this._webSocket!.close();
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
protected _doSubscribe<T extends SharedEvent>(subscription: EventSubscription<T>): Promise<string> {
|
|
538
|
-
if (!this._webSocket) {
|
|
539
|
-
return Promise.reject("Not connected");
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
if (this._subscribeDeferred) {
|
|
543
|
-
return Promise.reject("There's already a pending subscription");
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
this._subscribeDeferred = new Deferred();
|
|
547
|
-
subscription.subscriptionId = WebSocketEventProvider._subscriptionCounter++ + "";
|
|
548
|
-
this._webSocket.send(SUBSCRIBE_MESSAGE_PREFIX + JSON.stringify(subscription));
|
|
549
|
-
return this._subscribeDeferred.promise;
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
protected _doUnsubscribe(subscriptionId: string): void {
|
|
553
|
-
if (!this._webSocket) {
|
|
554
|
-
return;
|
|
555
|
-
}
|
|
556
|
-
let cancelSubscription: CancelEventSubscription<SharedEvent> = {
|
|
557
|
-
subscriptionId: subscriptionId
|
|
558
|
-
};
|
|
559
|
-
this._webSocket.send(UNSUBSCRIBE_MESSAGE_PREFIX + JSON.stringify(cancelSubscription));
|
|
560
|
-
if (Object.keys(this._subscriptionMap).length == 0 && this._renewalTimer) {
|
|
561
|
-
clearInterval(this._renewalTimer);
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
protected _doRenewal() {
|
|
566
|
-
if (!this._webSocket) {
|
|
567
|
-
return;
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
let renewSubscriptions: RenewEventSubscriptions = {
|
|
571
|
-
subscriptionIds: Object.keys(this._subscriptionMap)
|
|
572
|
-
};
|
|
573
|
-
this._webSocket.send(RENEW_MESSAGE_PREFIX + JSON.stringify(renewSubscriptions));
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
protected _doSend<T extends SharedEvent>(event: T): void {
|
|
577
|
-
if (!this._webSocket) {
|
|
578
|
-
return;
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
let message = EVENT_MESSAGE_PREFIX + JSON.stringify(event);
|
|
582
|
-
this._webSocket.send(message);
|
|
583
|
-
}
|
|
584
|
-
}
|
package/src/index.d.ts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import 'url-search-params-polyfill';
|
|
2
|
-
import { Console } from "./console";
|
|
3
|
-
import { EventProvider, EventProviderStatus } from "./event";
|
|
4
|
-
export declare enum ORError {
|
|
5
|
-
NONE = "NONE",
|
|
6
|
-
MANAGER_FAILED_TO_LOAD = "MANAGER_FAILED_TO_LOAD",
|
|
7
|
-
KEYCLOAK_FAILED_TO_LOAD = "KEYCLOAK_FAILED_TO_LOAD",
|
|
8
|
-
AUTH_TYPE_UNSUPPORTED = "AUTH_TYPE_UNSUPPORTED",
|
|
9
|
-
CONSOLE_ERROR = "CONSOLE_INIT_ERROR",
|
|
10
|
-
EVENTS_CONNECTION_ERROR = "EVENTS_CONNECTION_ERROR"
|
|
11
|
-
}
|
|
12
|
-
export declare enum Auth {
|
|
13
|
-
KEYCLOAK = "KEYCLOAK",
|
|
14
|
-
BASIC = "BASIC",
|
|
15
|
-
NONE = "NONE"
|
|
16
|
-
}
|
|
17
|
-
export declare enum OREvent {
|
|
18
|
-
INIT = "INIT",
|
|
19
|
-
AUTHENTICATED = "AUTHENTICATED",
|
|
20
|
-
ERROR = "ERROR",
|
|
21
|
-
READY = "READY",
|
|
22
|
-
CONSOLE_INIT = "CONSOLE_INIT",
|
|
23
|
-
CONSOLE_READY = "CONSOLE_READY",
|
|
24
|
-
EVENTS_CONNECTED = "EVENTS_CONNECTED",
|
|
25
|
-
EVENTS_CONNECTING = "EVENTS_CONNECTING",
|
|
26
|
-
EVENTS_DISCONNECTED = "EVENTS_DISCONNECTED"
|
|
27
|
-
}
|
|
28
|
-
export declare enum EventProviderType {
|
|
29
|
-
WEBSOCKET = "WEBSOCKET",
|
|
30
|
-
POLLING = "POLLING"
|
|
31
|
-
}
|
|
32
|
-
export interface Credentials {
|
|
33
|
-
username: string;
|
|
34
|
-
password: string;
|
|
35
|
-
}
|
|
36
|
-
export interface LoginOptions {
|
|
37
|
-
redirectUrl?: string;
|
|
38
|
-
credentials?: Credentials;
|
|
39
|
-
}
|
|
40
|
-
export interface ManagerConfig {
|
|
41
|
-
managerUrl: string;
|
|
42
|
-
keycloakUrl?: string;
|
|
43
|
-
appVersion?: string;
|
|
44
|
-
auth?: Auth;
|
|
45
|
-
realm: string;
|
|
46
|
-
autoLogin?: boolean;
|
|
47
|
-
credentials?: Credentials;
|
|
48
|
-
consoleAutoEnable?: boolean;
|
|
49
|
-
eventProviderType?: EventProviderType;
|
|
50
|
-
pollingIntervalMillis?: number;
|
|
51
|
-
}
|
|
52
|
-
export declare type EventCallback = (event: OREvent) => any;
|
|
53
|
-
export declare class Manager {
|
|
54
|
-
readonly username: string;
|
|
55
|
-
readonly error: ORError;
|
|
56
|
-
readonly authenticated: boolean;
|
|
57
|
-
readonly initialised: boolean;
|
|
58
|
-
readonly ready: boolean;
|
|
59
|
-
readonly config: ManagerConfig;
|
|
60
|
-
readonly roles: string[];
|
|
61
|
-
readonly managerVersion: string;
|
|
62
|
-
readonly isManagerAvailable: boolean | "";
|
|
63
|
-
readonly isError: boolean;
|
|
64
|
-
readonly connectionStatus: EventProviderStatus | null;
|
|
65
|
-
readonly console: Console;
|
|
66
|
-
readonly events: EventProvider | null;
|
|
67
|
-
protected static normaliseConfig(config: ManagerConfig): ManagerConfig;
|
|
68
|
-
private _error;
|
|
69
|
-
private _config;
|
|
70
|
-
private _authenticated;
|
|
71
|
-
private _ready;
|
|
72
|
-
private _name;
|
|
73
|
-
private _username;
|
|
74
|
-
private _keycloak;
|
|
75
|
-
private _roles;
|
|
76
|
-
private _keycloakUpdateTokenInterval?;
|
|
77
|
-
private _managerVersion;
|
|
78
|
-
private _listeners;
|
|
79
|
-
private _console;
|
|
80
|
-
private _events;
|
|
81
|
-
isManagerSameOrigin(): boolean;
|
|
82
|
-
addListener(callback: EventCallback): void;
|
|
83
|
-
removeListener(callback: EventCallback): void;
|
|
84
|
-
init(config: ManagerConfig): Promise<boolean>;
|
|
85
|
-
protected doInit(): Promise<boolean>;
|
|
86
|
-
protected doAuthInit(): Promise<boolean>;
|
|
87
|
-
protected doRestApiInit(): boolean;
|
|
88
|
-
protected doEventsSubscriptionInit(): Promise<boolean>;
|
|
89
|
-
protected onEventsProviderStatusChanged(status: EventProviderStatus): void;
|
|
90
|
-
protected doConsoleInit(): Promise<boolean>;
|
|
91
|
-
logout(redirectUrl?: string): void;
|
|
92
|
-
login(options?: LoginOptions): void;
|
|
93
|
-
isSuperUser(): boolean;
|
|
94
|
-
getApiBaseUrl(): string;
|
|
95
|
-
getAppName(): string;
|
|
96
|
-
hasRole(role: string): boolean;
|
|
97
|
-
getAuthorizationHeader(): string | undefined;
|
|
98
|
-
getKeycloakToken(): string | undefined;
|
|
99
|
-
getRealm(): string | undefined;
|
|
100
|
-
protected isMobile(): boolean;
|
|
101
|
-
protected _onAuthenticated(): void;
|
|
102
|
-
protected loadAndInitialiseKeycloak(): Promise<boolean>;
|
|
103
|
-
protected updateKeycloakAccessToken(): Promise<boolean>;
|
|
104
|
-
protected _getNativeOfflineRefreshToken(): Promise<string | null>;
|
|
105
|
-
protected _emitEvent(event: OREvent): void;
|
|
106
|
-
protected _setError(error: ORError): void;
|
|
107
|
-
protected _setAuthenticated(authenticated: boolean): void;
|
|
108
|
-
}
|
|
109
|
-
declare const _default: Manager;
|
|
110
|
-
export default _default;
|