peer-connection/helpers/data-channel/closeDataChannel.js

import { DATA_CHANNEL_STATE, TAGS } from '../../../constants';
import { onDataChannelStateChanged } from '../../../skylink-events';
import MESSAGES from '../../../messages';
import HandleDataChannelStats from '../../../skylink-stats/handleDataChannelStats';
import logger from '../../../logger';
import PeerConnection from '../../index';
import { dispatchEvent } from '../../../utils/skylinkEventManager';
import Skylink from '../../../index';

const closeFn = (roomState, peerId, channelNameProp) => {
  const { dataChannels } = roomState;
  const targetDataChannel = dataChannels[peerId][channelNameProp];
  const { channelName, channelType } = targetDataChannel.channelName;

  if (targetDataChannel.readyState !== DATA_CHANNEL_STATE.CLOSED) {
    const { room } = roomState;
    const handleDataChannelStats = new HandleDataChannelStats();
    logger.log.DEBUG([peerId, TAGS.DATA_CHANNEL, channelNameProp, MESSAGES.DATA_CHANNEL.CLOSING]);

    handleDataChannelStats.send(room.id, DATA_CHANNEL_STATE.CLOSING, peerId, targetDataChannel.channel, channelNameProp);

    dispatchEvent(onDataChannelStateChanged({
      room,
      peerId,
      state: DATA_CHANNEL_STATE.CLOSING,
      channelName,
      channelType,
      bufferAmount: PeerConnection.getDataChannelBuffer(targetDataChannel.channel),
    }));

    targetDataChannel.channel.close();

    delete dataChannels[peerId][channelNameProp];
  }
};

const closeAllDataChannels = (roomState, peerId) => {
  const { dataChannels } = roomState;
  const channelNameProp = Object.keys(dataChannels[peerId]);
  for (let i = 0; i < channelNameProp.length; i += 1) {
    if (Object.hasOwnProperty.call(dataChannels[peerId], channelNameProp[i])) {
      closeFn(roomState, peerId, channelNameProp[i]);
    }
  }

  delete dataChannels[peerId];
};

/**
 * Function that closes the datachannel.
 * @param {SkylinkState} roomState
 * @param {String} peerId - The Peer Id.
 * @param {String} [channelProp=main] - The channel property.
 * @memberOf PeerConnection.PeerConnectionHelpers
 * @fires onDataChannelStateChanged
 */
const closeDataChannel = (roomState, peerId, channelProp = 'main') => {
  try {
    const updatedState = Skylink.getSkylinkState(roomState.room.id);
    const { dataChannels, room } = updatedState;

    if (!dataChannels[peerId] || !dataChannels[peerId][channelProp]) {
      logger.log.WARN([peerId, TAGS.DATA_CHANNEL, channelProp || null,
        MESSAGES.DATA_CHANNEL.ERRORS.NO_SESSIONS]);
      return;
    }

    if (channelProp === 'main') {
      closeAllDataChannels(updatedState, peerId);
      return;
    }

    closeFn(updatedState, peerId, channelProp);
    Skylink.setSkylinkState(updatedState, room.id);
  } catch (error) {
    logger.log.ERROR([peerId, TAGS.DATA_CHANNEL, channelProp || null,
      MESSAGES.DATA_CHANNEL.ERRORS.FAILED_CLOSING], error);
  }
};

export default closeDataChannel;