ng4-signalr
Version:
angular4 signalr library
400 lines (385 loc) • 14.9 kB
JavaScript
import { Subject } from 'rxjs';
import * as i0 from '@angular/core';
import { InjectionToken, Injectable, Inject, NgZone, NgModule } from '@angular/core';
class ConnectionStatus {
constructor(value) {
if (value == null || value < 0) {
throw new Error("Failed to create ConnectionStatus. Argument 'name' can not be null or empty.");
}
this._value = value;
}
get value() {
return this._value;
}
get name() {
return ConnectionStatus.names[Number.parseInt(this._value.toString(), 10)];
}
toString() {
return this.name;
}
equals(other) {
if (other == null) {
return false;
}
return this._value === other.value;
}
}
ConnectionStatus.names = ['connecting', 'connected', 'reconnecting', '', 'disconnected'];
// @dynamic
class ConnectionStatuses {
static get connecting() {
return ConnectionStatuses.statuses[0];
}
static get connected() {
return ConnectionStatuses.statuses[1];
}
static get reconnecting() {
return ConnectionStatuses.statuses[2];
}
static get disconnected() {
return ConnectionStatuses.statuses[3];
}
}
ConnectionStatuses.statuses = [
new ConnectionStatus(0),
new ConnectionStatus(1),
new ConnectionStatus(2),
new ConnectionStatus(4)
];
class BroadcastEventListener extends Subject {
constructor(event) {
super();
this.event = event;
if (event == null || event === '') {
throw new Error('Failed to create BroadcastEventListener. Argument \'event\' can not be empty');
}
}
}
class SignalRConnection {
constructor(jConnection, jProxies, zone, configuration) {
this._jProxies = jProxies;
this._defaultProxy = jProxies.values().next().value;
this._jConnection = jConnection;
this._zone = zone;
this._errors = this.wireUpErrorsAsObservable();
this._status = this.wireUpStatusEventsAsObservable();
this._configuration = configuration;
}
get errors() {
return this._errors;
}
get status() {
return this._status;
}
setQs(qs) {
this._jConnection.qs = qs;
}
getQs() {
return this._jConnection.qs;
}
start() {
console.log('Starting connection', this._jConnection);
const jTransports = this.convertTransports(this._configuration.transport);
const $promise = new Promise((resolve, reject) => {
this._jConnection
.start({
jsonp: this._configuration.jsonp,
transport: jTransports,
withCredentials: this._configuration.withCredentials,
})
.done(() => {
console.log('Connection established, ID: ' + this._jConnection.id);
console.log('Connection established, Transport: ' + this._jConnection.transport.name);
resolve(this);
})
.fail((error) => {
console.log('Could not connect');
reject('Failed to connect. Error: ' + error.message); // ex: Error during negotiation request.
});
});
return $promise;
}
stop() {
console.log('Stopping connection', this._jConnection);
this._jConnection.stop();
}
get id() {
return this._jConnection.id;
}
invoke(method, sproxy, ...parameters) {
if (method == null) {
throw new Error('SignalRConnection: Failed to invoke. Argument \'method\' can not be null');
}
this.log(`SignalRConnection. Start invoking \'${method}\'...`);
const $promise = new Promise((resolve, reject) => {
this.getCurrentProxy(sproxy).invoke(method, ...parameters)
.done((result) => {
this.log(`\'${method}\' invoked succesfully. Resolving promise...`);
resolve(result);
this.log(`Promise resolved.`);
})
.fail((err) => {
console.log(`Invoking \'${method}\' failed. Rejecting promise...`);
reject(err);
console.log(`Promise rejected.`);
});
});
return $promise;
}
listen(listener, sproxy) {
if (listener == null) {
throw new Error('Failed to listen. Argument \'listener\' can not be null');
}
this.log(`SignalRConnection: Starting to listen to server event with name ${listener.event}`);
this.getCurrentProxy(sproxy).on(listener.event, (...args) => {
this._zone.run(() => {
let casted = null;
if (args.length > 0) {
casted = args[0];
this.log('SignalRConnection.proxy.on invoked. Calling listener next() ...');
listener.next(casted);
this.log('listener next() called.');
}
});
});
}
listenFor(event, sproxy) {
if (event == null || event === '') {
throw new Error('Failed to listen. Argument \'event\' can not be empty');
}
const listener = new BroadcastEventListener(event);
this.listen(listener, sproxy);
return listener;
}
getCurrentProxy(sproxy) {
if (!sproxy) {
return this._defaultProxy;
}
else {
return this._jProxies.get(sproxy);
}
}
convertTransports(transports) {
if (transports instanceof Array) {
return transports.map((t) => t.name);
}
return transports.name;
}
wireUpErrorsAsObservable() {
const sError = new Subject();
this._jConnection.error((error) => {
// this._zone.run(() => { /*errors don't need to run in a zone*/
sError.next(error);
// });
});
return sError;
}
wireUpStatusEventsAsObservable() {
const sStatus = new Subject();
// aggregate all signalr connection status handlers into 1 observable.
// handler wire up, for signalr connection status callback.
this._jConnection.stateChanged((change) => {
this._zone.run(() => {
sStatus.next(new ConnectionStatus(change.newState));
});
});
return sStatus.asObservable();
}
/*private onBroadcastEventReceived<T>(listener: BroadcastEventListener<T>, ...args: any[]) {
this.log('SignalRConnection.proxy.on invoked. Calling listener next() ...');
let casted: T = null;
if (args.length > 0) {
casted = (args[0] as T);
}
this._zone.run(() => {
listener.next(casted);
});
this.log('listener next() called.');
}*/
log(...args) {
if (this._jConnection.logging === false) {
return;
}
console.log(args.join(', '));
}
}
class ConnectionTransport {
constructor(name) {
if (name == null || name === "") {
throw new Error("Failed to create ConnectionTransport. Argument 'name' can not be null or empty.");
}
this._name = name;
}
get name() {
return this._name;
}
toString() {
return this._name;
}
equals(other) {
if (other == null) {
return false;
}
return this._name === other.name;
}
}
// @dynamic
class ConnectionTransports {
static get foreverFrame() {
return ConnectionTransports.transports[0];
}
static get longPolling() {
return ConnectionTransports.transports[1];
}
static get serverSentEvents() {
return ConnectionTransports.transports[2];
}
static get webSockets() {
return ConnectionTransports.transports[3];
}
static get auto() {
return ConnectionTransports.transports[4];
}
}
ConnectionTransports.transports = [
new ConnectionTransport("foreverFrame"),
new ConnectionTransport("longPolling"),
new ConnectionTransport("serverSentEvents"),
new ConnectionTransport("webSockets"),
new ConnectionTransport("auto"),
];
class SignalRConfiguration {
constructor() {
this.hubNames = [];
this.logging = false;
this.qs = null;
this.url = null;
this.jsonp = false;
this.withCredentials = false;
this.transport = ConnectionTransports.auto;
}
}
const SIGNALR_JCONNECTION_TOKEN = new InjectionToken('SIGNALR_JCONNECTION_TOKEN');
class SignalR {
constructor(configuration, zone, jHubConnectionFn) {
this._configuration = configuration;
this._zone = zone;
this._jHubConnectionFn = jHubConnectionFn;
}
createConnection(options) {
const configuration = this.merge(options ? options : {});
try {
const serializedQs = JSON.stringify(configuration.qs);
const serializedTransport = JSON.stringify(configuration.transport);
if (configuration.logging) {
console.log(`Creating connecting with multiple HUBS support!...`);
console.log(`configuration:[url: '${configuration.url}'] ...`);
configuration.hubNames.forEach((element) => {
console.log(`configuration:[hubName: '${element}'] ...`);
});
console.log(`configuration:[qs: '${serializedQs}'] ...`);
console.log(`configuration:[transport: '${serializedTransport}'] ...`);
}
}
catch (err) { /* empty */ }
// create connection object
const jConnection = this._jHubConnectionFn(configuration.url);
jConnection.logging = configuration.logging;
jConnection.qs = configuration.qs;
const jProxies = new Map();
configuration.hubNames.forEach((element) => {
// create a proxy
const jp = jConnection.createHubProxy(element);
jp.on('noOp', () => { });
jProxies.set(element, jp);
// !!! important. We need to register at least one function otherwise server callbacks will not work.
});
const hubConnection = new SignalRConnection(jConnection, jProxies, this._zone, configuration);
return hubConnection;
}
connect(options) {
return this.createConnection(options).start();
}
merge(overrides) {
const merged = new SignalRConfiguration();
merged.hubNames = overrides.hubNames || this._configuration.hubNames;
merged.url = overrides.url || this._configuration.url;
merged.qs = overrides.qs || this._configuration.qs;
merged.logging = this._configuration.logging;
merged.jsonp = overrides.jsonp || this._configuration.jsonp;
merged.withCredentials = overrides.withCredentials || this._configuration.withCredentials;
merged.transport = overrides.transport || this._configuration.transport;
return merged;
}
}
SignalR.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SignalR, deps: [{ token: SignalRConfiguration }, { token: i0.NgZone }, { token: SIGNALR_JCONNECTION_TOKEN }], target: i0.ɵɵFactoryTarget.Injectable });
SignalR.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SignalR });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SignalR, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: SignalRConfiguration }, { type: i0.NgZone }, { type: undefined, decorators: [{
type: Inject,
args: [SIGNALR_JCONNECTION_TOKEN]
}] }]; } });
const SIGNALR_CONFIGURATION = new InjectionToken('SIGNALR_CONFIGURATION');
function createSignalr(configuration, zone) {
const jConnectionFn = getJConnectionFn();
return new SignalR(configuration, zone, jConnectionFn);
}
function getJConnectionFn() {
const jQuery = getJquery();
const hubConnectionFn = jQuery.hubConnection;
if (hubConnectionFn == null) {
// tslint:disable-next-line:max-line-length
throw new Error('Signalr failed to initialize. Script \'jquery.signalR.js\' is missing. Please make sure to include \'jquery.signalR.js\' script.');
}
return hubConnectionFn;
}
function getJquery() {
const jQuery = window.jQuery;
if (jQuery == null) {
// tslint:disable-next-line:max-line-length
throw new Error('Signalr failed to initialize. Script \'jquery.js\' is missing. Please make sure to include jquery script.');
}
return jQuery;
}
class SignalRModule {
static forRoot(getSignalRConfiguration) {
return {
ngModule: SignalRModule,
providers: [
{
provide: SIGNALR_CONFIGURATION,
useFactory: getSignalRConfiguration
},
{
deps: [SIGNALR_CONFIGURATION, NgZone],
provide: SignalR,
useFactory: (createSignalr)
}
],
};
}
static forChild() {
throw new Error("forChild method not implemented");
}
}
SignalRModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SignalRModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
SignalRModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: SignalRModule });
SignalRModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SignalRModule, providers: [{
provide: SignalR,
useValue: SignalR
}] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SignalRModule, decorators: [{
type: NgModule,
args: [{
providers: [{
provide: SignalR,
useValue: SignalR
}]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { BroadcastEventListener, ConnectionStatus, ConnectionStatuses, ConnectionTransport, ConnectionTransports, SignalR, SignalRConfiguration, SignalRConnection, SignalRModule };
//# sourceMappingURL=ng4-signalr.mjs.map