All files / packages/tao-socket-io/src index.js

18.75% Statements 9/48
6.67% Branches 2/30
0% Functions 0/14
20.45% Lines 9/44
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73    2x 2x 1x 1x 1x   1x   1x                 1x                             1x                                                                            
import { Channel, Source } from '@tao.js/utils';
 
const DEFAULT_NAMESPACE = 'tao';
const IS_SERVER = typeof window === 'undefined';
const EMIT_EVENT = IS_SERVER ? 0 : 1;
const ON_EVENT = IS_SERVER ? 1 : 0;
const EVENTS = ['fromServer', 'fromClient'];
 
const NOOP = () => {};
 
const socketHandler = socket => (tao, data) => {
  socket.emit(EVENTS[EMIT_EVENT], { tao, data });
};
 
function decorateNetwork(TAO, socket) {
  const fromHandler = handler =>
    socket.on(EVENTS[ON_EVENT], ({ tao, data }) => handler(tao, data));
  const toEmit = (tao, data) => socket.emit(EVENTS[EMIT_EVENT], { tao, data });
  const source = new Source(TAO, toEmit, fromHandler);
  return source;
}
 
function decorateSocket(TAO, socket) {
  socket.on(EVENTS[ON_EVENT], ({ tao, data }) => {
    TAO.setCtx(tao, data);
  });
 
  const handler = socketHandler(socket);
  TAO.addInlineHandler({}, handler);
  socket.on('disconnect', () => {
    TAO.removeInlineHandler({}, handler);
  });
}
 
const ioMiddleware = (TAO, onConnect) => (socket, next) => {
  let clientTAO = new Channel(TAO, socket.id);
  let onDisconnect = NOOP;
  decorateSocket(clientTAO, socket);
  if (onConnect && typeof onConnect === 'function') {
    onDisconnect = onConnect(clientTAO, socket.id);
    onDisconnect = typeof onDisconnect === 'function' ? onDisconnect : NOOP;
  }
  socket.on('disconnect', reason => {
    onDisconnect(reason);
    clientTAO = null;
    onDisconnect = null;
  });
 
  if (next && typeof next === 'function') {
    return next();
  }
};
 
export default function wireTaoJsToSocketIO(TAO, io, opts = {}) {
  const ns = opts.namespace || opts.ns || DEFAULT_NAMESPACE;
  if (!IS_SERVER) {
    if (io && typeof io === 'function') {
      const host = opts.host || '';
      const socket = io(`${host}/${ns}`);
      const source = decorateNetwork(TAO, socket);
      return socket;
    }
  } else {
    const { onConnect } = opts;
    if (io && typeof io.of === 'function') {
      const namespacedEngine = io.of(`/${ns}`);
      namespacedEngine.use(ioMiddleware(TAO, onConnect));
    } else {
      return ioMiddleware(TAO, onConnect);
    }
  }
}