Home Reference Source

src/datapipe/WacDataPipe.js

import {bindMethods} from '../utils/bindMethods';

import {DataPipe} from './DataPipe';
import {DataPipeStatus} from './DataPipeStatus';
import {DataPipeType} from './DataPipeType';

export class WacDataPipe extends DataPipe {
	constructor(id, type, stack, participants, label) {
		super(id, type, stack, participants, label);
		this.datapipeService = stack.getDatapipeService();
		this.gatewayUsername = stack.wStack.getCurrentCredential().data.username;
		bindMethods(this, ['onStatus', 'onData', 'onDelete', 'onUpdate']);
		this.makeBindings();
	}

	/**
	 * @Override
	 */
	async connect() {
		if (this.status !== DataPipeStatus.UNCONNECTED) {
			throw new Error('invalid-state');
		}
		this.status = DataPipeStatus.CONNECTING;
		try {
			if (this.type === DataPipeType.OUTGOING) {
				const datapipe = await this.datapipeService.create(this.label, this.participants);
				this.internalId = datapipe.id;
			}
			await this.datapipeService.accept(this.internalId);
			await this.when(DataPipeStatus.CONNECTED);
		} catch (error) {
			this.status = DataPipeStatus.DISCONNECTED;
			throw error;
		}
		return this;
	}

	/**
	 * @Override
	 */
	async disconnect() {
		if (this.status !== DataPipeStatus.CONNECTED) {
			throw new Error('invalid-state');
		}
		await this.datapipeService.delete(this.internalId);
		this.status = DataPipeStatus.DISCONNECTED;
		return this;
	}

	/**
	 * @Override
	 */
	async reject() {
		if (this.status !== DataPipeStatus.UNCONNECTED || this.type !== DataPipeType.INCOMING) {
			throw new Error('invalid-state');
		}
		await this.datapipeService.delete(this.internalId);
		this.status = DataPipeStatus.DISCONNECTED;
		return this;
	}

	/**
	 * @Override
	 */
	async send(data) {
		if (this.status !== DataPipeStatus.CONNECTED) {
			throw new Error('invalid-state');
		}
		await this.datapipeService.send(this.internalId, data);
		return this;
	}

	/**
	 * @private
	 * @return {WacDataPipe}
	 */
	makeBindings() {
		this.on('status', this.onStatus);
		this.datapipeService.emitter.on('delete', this.onDelete);
		this.datapipeService.emitter.on('data', this.onData);
		this.datapipeService.emitter.on('update', this.onUpdate);
		return this;
	}

	/**
	 * @private
	 * @return {WacDataPipe}
	 */
	destroyBindings() {
		this.off('status', this.onStatus);
		this.datapipeService.emitter.off('delete', this.onDelete);
		this.datapipeService.emitter.off('data', this.onData);
		this.datapipeService.emitter.off('update', this.onUpdate);
		return this;
	}

	/**
	 * Destroy bindings when disconnected state reached.
	 * @private
	 */
	onStatus() {
		if (this.status === DataPipeStatus.DISCONNECTED) {
			this.destroyBindings();
		}
	}

	/**
	 * @private
	 */
	onDelete(event) {
		if (event.id === this.internalId) {
			this.status = DataPipeStatus.DISCONNECTED;
		}
	}

	/**
	 * @private
	 */
	onData(event) {
		if (event.id === this.internalId) {
			this.emit('data', event.payload);
			this.emit('data-with-info', {
				data: event.payload,
				from: event.from,
				ts: event.ts,
			});
		}
	}

	/**
	 * @private
	 */
	onUpdate(event) {
		if (event.id === this.internalId && event.connected.includes(this.gatewayUsername)) {
			this.status = DataPipeStatus.CONNECTED;
		}
	}
}