all files / src/components/ broadcaster.js

28% Statements 14/50
0% Branches 0/17
100% Functions 0/0
29.17% Lines 14/48
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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 11120×                                                                                                                                                                                                  
import path from 'path'
import createDebugger from 'debug'
import serverDestroy from 'server-destroy'
import socketIO from 'socket.io'
import { createServer  } from 'http'
import { ENV_PATH } from '../constants/paths.js'
import {
    SET_BROADCASTER_PREPARATIONS,
    CLEAR_BROADCASTER_PREPARATIONS,
    CLEAR_BROADCASTER_MESSAGE,
    CLEAR_BROADCASTER_FILE_CHANGE,
    CLEAR_BROADCASTER_RELOAD
} from '../constants/actionTypes.js'
import { setModifiedFile, handleError } from '../actions/creators.js'
 
const debug = createDebugger('unistack:broadcaster')
 
const server = createServer()
const io = socketIO(server)
const sockets = new Set([])
 
const Broadcaster = ({ dispatch, getState }) => {
    const state = getState()
    const broadcast = getStateLeaf(state, 'BROADCAST')
    const broadcasting = getStateLeaf(state, 'BROADCASTING')
    debug('Checking if server needs to be initialized...')
    if (broadcast && !broadcasting) {
        debug('!!!!--Preparing to initialize socket server...')
        dispatch({ type: SET_BROADCASTER_PREPARATIONS })
        io.on('connection', socket => {
            sockets.add(socket)
            socket.on('disconnect', () => {
                sockets.delete(socket)
            })
            socket.on('identification', name => {
                debug('Connected client: %s', name)
            })
        })
        return new Promise((resolve, reject) => {
            server.listen(5776, error => {
                if (error) reject(error)
                resolve({ server, io })
            })
            serverDestroy(server)
        })
        .then(() => {
            debug('@@@@--Successfully initialized server at port 5776!')
            return dispatch({ type: CLEAR_BROADCASTER_PREPARATIONS })
        })
        .catch(error => {
            debug('@@@@--Failed to initialize server: %s', error.stack)
        })
    }
 
    const message = getStateLeaf(state, 'MESSAGE')
    debug('Checking if a there is a message to share...')
    if (message) {
        debug('Yep, we sure do.')
        console.log(message)
        sockets.forEach(socket => {
            debug('Emitting to sockets')
            socket.emit('message', message)
        })
        return dispatch({ type: CLEAR_BROADCASTER_MESSAGE })
    }
 
    debug('Checking if a browser reload is needed...')
    const reload = getStateLeaf(state, 'RELOAD')
    if (reload) {
        debug('Yep, we sure do.')
        console.log('Reloading browser!')
        sockets.forEach(socket => {
            debug('Emitting to sockets')
            socket.emit('reload')
        })
        return dispatch({ type: CLEAR_BROADCASTER_RELOAD })
    }
 
    debug('Checking if there was a file change event...')
    const fileChange = getStateLeaf(state, 'FILE_CHANGE')
    if (fileChange) {
        debug('Yep, there was file change: %s %s', fileChange.name, fileChange.type)
        const absolutePath = fileChange.name
        const relativePath = path.relative(ENV_PATH, absolutePath)
        console.log(`File (${fileChange.type}): ${relativePath}`)
        sockets.forEach(socket => {
            debug('Emitting to sockets %s - %s', relativePath, absolutePath)
            socket.emit('change', { path: relativePath, absolutePath })
        })
        return dispatch({ type: CLEAR_BROADCASTER_FILE_CHANGE })
    }
    debug('Nothing to do.')
}
 
const getStateLeaf = (state, leaf) => {
    switch(leaf) {
        case 'BROADCAST':
            return state.broadcaster.broadcast
        case 'BROADCASTING':
            return state.broadcaster.broadcasting
        case 'MESSAGE':
            return state.broadcaster.message
        case 'RELOAD':
            return state.broadcaster.reload
        case 'FILE_CHANGE':
            return state.broadcaster.fileChange
    }
}
 
export default Broadcaster