@engie-group/ngx-gem-spaas
Version:
This library contains services, components, images and styles to provide a unified look and way-of-working throughout GEM SPaaS.
256 lines (248 loc) • 12.1 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, Optional, Inject, input, output, Component, HostListener, NgModule } from '@angular/core';
import { BaseComponent } from '@engie-group/ngx-gem-spaas';
import { DateTime } from 'luxon';
import * as autobahn from 'autobahn-browser';
import { ReplaySubject } from 'rxjs';
import * as i2 from '@angular/material/tooltip';
import { MatTooltipModule } from '@angular/material/tooltip';
import { CommonModule } from '@angular/common';
var CrossbarStates;
(function (CrossbarStates) {
CrossbarStates["open"] = "open";
CrossbarStates["closed"] = "closed";
})(CrossbarStates || (CrossbarStates = {}));
class CrossbarResponseModel {
constructor(ts = '', topic = '') {
this.topic = '';
this.type = '';
this.received = ts || DateTime.now().toISO();
this.topic = topic;
}
}
class CrossbarSendModel {
constructor() {
this.type = '';
}
}
/**
* Crossbar configuration object to be provided via "forRoot" method.
*
* @property {string} xbarUrl the URL of your crossbar websocket server
* @property {string[]} xbarTopics the list of topics to listen to on the crossbar websocket server
* @property {string} xbarTopicsPrefix prefix to be added to all topics, usually indicating the environment.
* For example, on the Cylon xbar server, prefixes 'cb.preprod' and 'cb.prod' are used. Leave empty if none.
* @property {string} xbarUidPwd to provide a user-id and password for the xbar basic auth (in the form of "ui:pwd") [optional]
*/
class CrossbarConfigModel {
constructor(props) {
this.xbarTopics = [];
this.xbarTopicsPrefix = '';
this.xbarUidPwd = '';
this.xbarUrl = '';
this.xbarTopics = props.xbarTopics || [];
this.xbarTopicsPrefix = props.xbarTopicsPrefix || '';
this.xbarUidPwd = props.xbarUidPwd || '';
this.xbarUrl = props.xbarUrl || '';
}
}
// @ts-ignore
class CrossbarService {
constructor(crossbarConfig) {
this.crossbarConfig = crossbarConfig;
this.crossbarMsg$ = new ReplaySubject(1);
this.crossbarState$ = new ReplaySubject(1);
}
// ********************************************************************************************************
// AUTOBAHN
// ********************************************************************************************************
startConnection() {
if (!this.crossbarConfig?.xbarUrl || !this.crossbarConfig?.xbarTopics?.length) {
throw new Error('please provide a valid SpaasCrossbarConfigModel using the forRoot method of the SpaasCrossbarModule');
}
// CONNECT
this.crossbar = new autobahn.Connection({
url: this.crossbarConfig.xbarUrl,
realm: 'realm1',
headers: { 'Authorization': btoa(this.crossbarConfig.xbarUidPwd || 'none:none') }
});
this.crossbar.open();
// CONNECT EVENTS
this.crossbar.onopen = (session) => {
// console.log('crossbar websocket opened');
this.crossbarSession = session;
const resp = new CrossbarResponseModel();
resp.data = 'websocket connected successfully';
resp.type = 'connected';
this.crossbarConfig.xbarTopics.forEach((topic) => this.subscribeToTopic(topic));
this.newWsMessage(resp);
this.newWsState(CrossbarStates.open);
};
// CLOSE EVENT
this.crossbar.onclose = (e) => {
const resp = new CrossbarResponseModel();
if (e.wasClean) {
console.log('crossbar websocket closed');
resp.data = 'websocket disconnected';
resp.type = 'disconnected';
}
else {
console.log('crossbar websocket closed due to error');
// CLOSE WAS TRIGGERED BY AN ERROR (WS ERROR ALWAYS CALLS WS CLOSE)
resp.data = JSON.stringify(e);
resp.type = 'error';
}
this.newWsMessage(resp);
this.newWsState(CrossbarStates.closed);
};
// HARD DISCONNECT FROM BROWSER
return () => {
if (this.crossbar) {
this.crossbar.close();
}
};
}
subscribeToTopic(topic) {
if (this.crossbarSession) {
const topicString = this.crossbarConfig.xbarTopicsPrefix ? this.crossbarConfig.xbarTopicsPrefix + '.' + topic : topic;
this.crossbarSession.subscribe(topicString, (args, kwargs, details) => this.onChannelUpdate(args, kwargs, details));
}
}
onChannelUpdate(args, kwargs, details) {
const data = args[0];
const resp = new CrossbarResponseModel();
resp.data = data?.data || data;
resp.topic = details.topic ? details.topic.replace(this.crossbarConfig.xbarTopicsPrefix + '.', '') : '';
resp.type = data?.type || '';
this.newWsMessage(resp);
}
stopConnection() {
if (this.crossbar) {
this.crossbar.close();
}
}
sendMessage(topic, e, excludeMe = false) {
if (this.crossbarSession) {
this.crossbarSession.publish(this.crossbarConfig.xbarTopicsPrefix ? this.crossbarConfig.xbarTopicsPrefix + '.' + topic : topic, [e], null, { exclude_me: excludeMe });
}
}
// ********************************************************************************************************
// BROADCAST DATA
// ********************************************************************************************************
newWsMessage(msg) {
this.crossbarMsg$.next(msg);
}
onNewWsMessage() {
return this.crossbarMsg$.asObservable();
}
newWsState(state) {
this.crossbarState$.next(state);
}
onNewWsState() {
return this.crossbarState$.asObservable();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: CrossbarService, deps: [{ token: CrossbarConfigModel, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: CrossbarService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: CrossbarService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [{ type: CrossbarConfigModel, decorators: [{
type: Optional
}, {
type: Inject,
args: [CrossbarConfigModel]
}] }] });
/**
* This component creates the connection to the crossbar websocket server and
* shows a state indicator in the bottom left corner of your app.
* */
class CrossbarStateComponent extends BaseComponent {
constructor(crossbarService) {
super();
this.crossbarService = crossbarService;
this.fromBottomPx = input(14);
this.crossbarState = output();
this.crossbarActive = false;
}
onFocus() {
// ALSO CHECK IF TAB IS VISIBLE
if (document.visibilityState !== 'hidden') {
this.crossbarConnect();
}
}
ngOnInit() {
this.crossbarConnect();
}
ngOnDestroy() {
this.crossbarService.stopConnection();
super.ngOnDestroy();
}
// ********************************************************************************************************
// LOADING DATA
// ********************************************************************************************************
crossbarConnect() {
if (!this.crossbarService.crossbar ||
!this.crossbarService.crossbar.isConnected ||
!this.crossbarService.crossbar.isOpen) {
this.wsCrossbarStateSubscribe();
this.crossbarService.startConnection();
}
else {
this.crossbarActive = true;
}
}
wsCrossbarStateSubscribe() {
this.crossbarService.onNewWsState()
.subscribe((state) => {
this.crossbarActive = state === CrossbarStates.open;
this.crossbarState.emit(state);
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: CrossbarStateComponent, deps: [{ token: CrossbarService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.1.5", type: CrossbarStateComponent, isStandalone: false, selector: "spaas-crossbar", inputs: { fromBottomPx: { classPropertyName: "fromBottomPx", publicName: "fromBottomPx", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { crossbarState: "crossbarState" }, host: { listeners: { "window:focus": "onFocus($event)" } }, usesInheritance: true, ngImport: i0, template: "<div [class.nok]=\"!crossbarActive\"\r\n [class.ok]=\"crossbarActive\"\r\n [style.bottom.px]=\"fromBottomPx()\"\r\n class=\"ws-state\"\r\n matTooltip=\"{{crossbarActive ? 'live update OK' : 'live update NOK'}}\">\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: CrossbarStateComponent, decorators: [{
type: Component,
args: [{ selector: 'spaas-crossbar', standalone: false, template: "<div [class.nok]=\"!crossbarActive\"\r\n [class.ok]=\"crossbarActive\"\r\n [style.bottom.px]=\"fromBottomPx()\"\r\n class=\"ws-state\"\r\n matTooltip=\"{{crossbarActive ? 'live update OK' : 'live update NOK'}}\">\r\n</div>\r\n" }]
}], ctorParameters: () => [{ type: CrossbarService }], propDecorators: { onFocus: [{
type: HostListener,
args: ['window:focus', ['$event']]
}] } });
class SpaasCrossbarModule {
static forRoot(config) {
return {
ngModule: SpaasCrossbarModule,
providers: [{ provide: CrossbarConfigModel, useValue: config }]
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SpaasCrossbarModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.5", ngImport: i0, type: SpaasCrossbarModule, declarations: [CrossbarStateComponent], imports: [CommonModule,
MatTooltipModule], exports: [CrossbarStateComponent] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SpaasCrossbarModule, imports: [CommonModule,
MatTooltipModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SpaasCrossbarModule, decorators: [{
type: NgModule,
args: [{
declarations: [
CrossbarStateComponent,
],
exports: [
CrossbarStateComponent,
],
imports: [
CommonModule,
MatTooltipModule,
],
providers: []
}]
}] });
// MODULE
/**
* Generated bundle index. Do not edit.
*/
export { CrossbarConfigModel, CrossbarResponseModel, CrossbarSendModel, CrossbarService, CrossbarStateComponent, CrossbarStates, SpaasCrossbarModule };
//# sourceMappingURL=engie-group-ngx-gem-spaas-crossbar.mjs.map