core/src/channel/index.ts

117 lines
2.8 KiB
TypeScript

import { IPlugin } from '../plugin';
import { IMessage, Protocol } from '../types';
import { ScopedEventEmitter } from '../util/events';
export interface IChannel {
name: string;
plugins: string[];
enabled: boolean;
}
// TODO: Source specification to support plugin services.
export class ChannelManager {
private channels: IChannel[] = [];
constructor(private stream: ScopedEventEmitter) {}
public static determinePlugin(source: any): IPlugin | null {
if (source != null) {
if (source.manifest) {
return source;
}
if (source.plugin && source.plugin.manifest) {
return source.plugin;
}
}
return null;
}
public initialize(configured: IChannel[]): void {
this.addPreconfiguredChannels(configured);
for (const event of ['message', 'event', 'special']) {
this.stream.on('channel', event, (data: IMessage) => {
const plugin = ChannelManager.determinePlugin(data.source);
if (!plugin) {
return;
}
const source = plugin.manifest.name;
const emitTo = this.getChannelsByPluginName(source);
for (const chan of emitTo) {
if (chan.plugins.length < 2) {
continue;
}
for (const pl of chan.plugins) {
if (pl !== source) {
this.stream.emitTo(pl, event, data);
}
}
}
});
}
}
private getChannelsByPluginName(plugin: string): IChannel[] {
const list = [];
for (const chan of this.channels) {
if (chan.enabled === false) {
continue;
}
if (chan.plugins.indexOf(plugin) !== -1) {
list.push(chan);
}
}
return list;
}
private addPreconfiguredChannels(channels: IChannel[]): void {
for (const chan of channels) {
if (!chan.name) {
throw new Error('Channel name is mandatory.');
}
if (!chan.plugins) {
throw new Error('Channel plugins list is mandatory.');
}
this.channels.push(chan);
}
}
public getChannelByName(name: string): IChannel | null {
for (const chan of this.channels) {
if (chan.name === name) {
return chan;
}
}
return null;
}
public addChannel(chan: IChannel): IChannel {
const exists = this.getChannelByName(chan.name);
if (exists) {
throw new Error('Channel by that name already exists!');
}
this.channels.push(chan);
return chan;
}
public removeChannel(chan: string | IChannel): void {
if (typeof chan === 'string') {
const getchan = this.getChannelByName(chan);
if (!getchan) {
throw new Error('Channel by that name doesn\'t exists!');
}
chan = getchan;
}
this.channels.splice(this.channels.indexOf(chan), 1);
}
public getAll(): any[] {
return this.channels;
}
}