@becomes/cms-cloud-client
Version:
SDK for accessing BCMS Cloud API
394 lines (393 loc) • 16.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SocketHandler = exports.SocketEventName = void 0;
const uuid_1 = require("uuid");
const socket_io_client_1 = require("socket.io-client");
// eslint-disable-next-line no-shadow
var SocketEventName;
(function (SocketEventName) {
SocketEventName["ORG"] = "ORG";
SocketEventName["INSTANCE"] = "INSTANCE";
SocketEventName["USER"] = "USER";
SocketEventName["REFRESH"] = "REFRESH";
SocketEventName["INVITATION"] = "INVITATION";
SocketEventName["CHECKOUT_COMPLETE"] = "CHECKOUT_COMPLETE";
SocketEventName["INSTANCE_LOG"] = "INSTANCE_LOG";
SocketEventName["INSTANCE_STATS"] = "INSTANCE_STATS";
SocketEventName["INSTANCE_FJE"] = "INSTANCE_FJE";
SocketEventName["INSTANCE_AF"] = "INSTANCE_AF";
SocketEventName["FEATURE"] = "FEATURE";
SocketEventName["LIMIT"] = "LIMIT";
SocketEventName["REDIRECT"] = "REDIRECT";
})(SocketEventName = exports.SocketEventName || (exports.SocketEventName = {}));
class SocketHandler {
sdk;
path;
isConnected = false;
socket = null;
subs = {};
constructor(sdk, path) {
this.sdk = sdk;
this.path = path;
const eventNames = Object.keys(SocketEventName);
this.isConnected = false;
this.socket = null;
eventNames.forEach((eventName) => {
this.subs[eventName] = {};
});
this.subs.ANY = {};
}
triggerSubs(eventName, event) {
for (const id in this.subs[eventName]) {
this.subs[eventName][id](event).catch((error) => {
// eslint-disable-next-line no-console
console.error(`Subs.${eventName}.${id} ->`, error);
});
}
if (eventName !== 'ANY') {
for (const id in this.subs.ANY) {
this.subs.ANY[id](event).catch((error) => {
// eslint-disable-next-line no-console
console.error(`Subs.${eventName}.${id} ->`, error);
});
}
}
}
initSocket() {
if (this.socket) {
this.socket.on(SocketEventName.REDIRECT, async (data) => {
if (data.uri.startsWith('/')) {
this.sdk.router.push({ path: data.uri });
}
else {
console.warn('Invalid redirect URI', data.uri);
}
});
this.socket.on(SocketEventName.USER, async (data) => {
const eventName = SocketEventName.USER;
if (data.t === 'update') {
await this.sdk.throwable(async () => {
await this.sdk.user.get({ id: data.u, skipCache: true });
});
}
else if (data.t === 'remove') {
this.sdk.store.user.remove(data.u);
}
this.triggerSubs(eventName, {
name: eventName,
data,
});
});
this.socket.on(SocketEventName.ORG, async (data) => {
const eventName = SocketEventName.ORG;
if (data.t === 'update') {
await this.sdk.throwable(async () => {
await this.sdk.org.get({ id: data.o, skipCache: true });
});
}
else if (data.t === 'remove') {
this.sdk.store.org.remove(data.o);
}
this.triggerSubs(eventName, {
name: eventName,
data,
});
});
this.socket.on(SocketEventName.INVITATION, async (data) => {
const eventName = SocketEventName.INVITATION;
if (data.t === 'update') {
await this.sdk.throwable(async () => {
await this.sdk.invitation.get({
instanceId: data.i,
invitationId: data.iv,
skipCache: true,
});
});
}
else if (data.t === 'remove') {
this.sdk.store.invitation.remove(data.iv);
}
this.triggerSubs(eventName, {
name: eventName,
data,
});
});
this.socket.on(SocketEventName.INSTANCE, async (data) => {
const eventName = SocketEventName.INSTANCE;
if (data.t === 'update') {
const item = this.sdk.store.instance.find((e) => e._id === data.i);
if (item) {
await this.sdk.throwable(async () => {
await this.sdk.instance.getById({
instanceId: data.i,
skipCache: true,
});
await this.sdk.user.getAll({ instanceId: data.i });
});
}
}
else if (data.t === 'remove') {
this.sdk.store.instance.remove(data.i);
}
this.triggerSubs(eventName, {
name: eventName,
data,
});
});
// this.socket.on(
// SocketEventName.INSTANCE_FJE,
// async (data: SocketInstanceFJEEvent) => {
// const eventName = SocketEventName.INSTANCE_FJE;
// if (data.t === 'update') {
// const item = cache.findOne<InstanceFJEV2>(
// 'instanceFJE',
// (e) => e._id === data.fi && e.instanceId === data.i,
// );
// if (item) {
// await throwable(async () => {
// await instanceFJEHandler.get({
// orgId: data.o,
// instanceId: data.i,
// fjeId: data.fi,
// skipCache: true,
// });
// });
// }
// } else if (data.t === 'remove') {
// const item = cache.findOne<InstanceFJEV2>(
// 'instanceFJE',
// (e) => e._id === data.fi && e.instanceId === data.i,
// );
// if (item) {
// cache.remove('instanceFJE', item);
// }
// }
// triggerSubs(eventName, {
// name: eventName,
// data,
// });
// },
// );
// this.socket.on(
// SocketEventName.INSTANCE_AF,
// async (data: SocketInstanceAdditionalFileEvent) => {
// const eventName = SocketEventName.INSTANCE_AF;
// if (data.t === 'update') {
// const item = cache.findOne<InstanceAdditionalFileV2>(
// 'instanceAdditionalFile',
// (e) => e._id === data.ai && e.instanceId === data.i,
// );
// if (item) {
// await throwable(async () => {
// await instanceAdditionalFileHandler.get({
// orgId: data.o,
// instanceId: data.i,
// afId: data.ai,
// skipCache: true,
// });
// });
// }
// } else if (data.t === 'remove') {
// const item = cache.findOne<InstanceAdditionalFileV2>(
// 'instanceAdditionalFile',
// (e) => e._id === data.ai && e.instanceId === data.i,
// );
// if (item) {
// cache.remove('instanceAdditionalFile', item);
// }
// }
// triggerSubs(eventName, {
// name: eventName,
// data,
// });
// },
// );
this.socket.on(SocketEventName.REFRESH, async (data) => {
const eventName = SocketEventName.REFRESH;
await this.sdk.throwable(async () => {
return await this.sdk.refreshAccessToken(true);
}, async (result) => {
if (result && typeof window !== 'undefined') {
if (data.rwo) {
const pathParts = window.location.pathname.split('/');
if (pathParts[3] && pathParts[3] === data.rwo.f) {
this.sdk.router.push({
path: `${pathParts.slice(0, 3).join('/')}/${data.rwo.t}/${pathParts.slice(4).join('/')}`,
replace: true,
});
}
}
if (data.rwi) {
const pathParts = window.location.pathname.split('/');
if (pathParts[5] && pathParts[5] === data.rwi.f) {
if (!data.rwi.t) {
this.sdk.router.push({
path: pathParts.slice(0, 4).join('/'),
replace: true,
});
}
else {
this.sdk.router.push({
path: `${pathParts.slice(0, 5).join('/')}/${data.rwi.t}/${pathParts.slice(6).join('/')}`,
replace: true,
});
}
}
}
}
});
this.triggerSubs(eventName, {
name: eventName,
data,
});
});
// this.socket.on(
// SocketEventName.CHECKOUT_COMPLETE,
// async (data: SocketCheckoutCompleteEvent) => {
// triggerSubs(SocketEventName.CHECKOUT_COMPLETE, {
// name: SocketEventName.CHECKOUT_COMPLETE,
// data,
// });
// },
// );
this.socket.on(SocketEventName.INSTANCE_LOG, async (data) => {
this.triggerSubs(SocketEventName.INSTANCE_LOG, {
name: SocketEventName.INSTANCE_LOG,
data,
});
});
this.socket.on(SocketEventName.INSTANCE_STATS, async (data) => {
const eventName = SocketEventName.INSTANCE_STATS;
const item = this.sdk.store.instance.findById(data.i);
if (item) {
item.server.stats = data.stats;
this.sdk.store.instance.set(item);
}
this.triggerSubs(eventName, {
name: eventName,
data,
});
});
this.socket.on(SocketEventName.FEATURE, async (data) => {
const eventName = SocketEventName.FEATURE;
if (data.t === 'update') {
await this.sdk.throwable(async () => {
const user = this.sdk.store.user.methods.me();
if (user && user.admin && user.admin.role === 'ADMIN') {
await this.sdk.feature.get({
id: data.f,
skipCache: true,
});
}
});
}
else if (data.t === 'remove') {
this.sdk.store.feature.remove(data.f);
}
this.triggerSubs(eventName, {
name: eventName,
data,
});
});
this.socket.on(SocketEventName.LIMIT, async (data) => {
const eventName = SocketEventName.LIMIT;
if (data.t === 'update') {
await this.sdk.throwable(async () => {
const user = this.sdk.store.user.methods.me();
if (user && user.admin && user.admin.role === 'ADMIN') {
await this.sdk.limit.get({
id: data.l,
skipCache: true,
});
}
});
}
else if (data.t === 'remove') {
this.sdk.store.limit.remove(data.l);
}
this.triggerSubs(eventName, {
name: eventName,
data,
});
});
}
}
id() {
return this.socket ? this.socket.id : null;
}
async connect() {
if (!this.isConnected) {
this.isConnected = true;
return await new Promise((resolve, reject) => {
try {
const token = this.sdk.storage.get('at');
if (!token) {
this.isConnected = false;
reject('You need to login to access socket.');
return;
}
this.socket = (0, socket_io_client_1.io)(this.sdk.apiOrigin, {
path: this.path,
transports: ['websocket'],
query: {
token: token,
},
autoConnect: false,
});
this.socket.connect();
this.socket.on('connect_error', (...data) => {
if (this.socket) {
this.socket.close();
}
this.isConnected = false;
reject(data);
});
this.socket.on('error', (data) => {
if (this.socket) {
this.socket.close();
}
this.isConnected = false;
reject(data);
});
this.socket.on('connect', () => {
// eslint-disable-next-line no-console
console.log('Successfully connected to Socket server.');
this.isConnected = true;
this.initSocket();
resolve();
});
this.socket.on('disconnect', () => {
this.isConnected = false;
// eslint-disable-next-line no-console
console.log('Disconnected from Socket server.');
});
}
catch (error) {
reject(error);
}
});
}
}
connected() {
return this.isConnected;
}
disconnect() {
if (this.socket && this.isConnected) {
this.socket.disconnect();
this.isConnected = false;
}
}
emit(event, data) {
if (this.socket) {
this.socket.emit(event, data);
}
}
subscribe(event, callback) {
const id = (0, uuid_1.v4)();
this.subs[event][id] = callback;
return () => {
delete this.subs[event][id];
};
}
}
exports.SocketHandler = SocketHandler;