Skip to content
Snippets Groups Projects
server.js 4.65 KiB
Newer Older
  • Learn to ignore specific revisions
  • Jake Read's avatar
    Jake Read committed
    // file system to load / look at our available modules / edit them 
    const fs = require('fs')
    
    Jake Read's avatar
    Jake Read committed
    // express serves files, http makes the connection
    const app = require('express')()
    const http = require('http').Server(app)
    
    Jake Read's avatar
    Jake Read committed
    // websocket does websocket
    const WebSocket = require('ws')
    
    Jake Read's avatar
    Jake Read committed
    // serving this handful of static files
    app.get('/', (req, res) => {
        console.log('client req /')
        res.sendFile(__dirname + '/client/index.html')
    })
    
    app.get('/:file', (req, res) => {
        console.log('client req', req.params.file)
        res.sendFile(__dirname + '/client/' + req.params.file)
    })
    
    
    Jake Read's avatar
    Jake Read committed
    // and listening for requests here
    const wss = new WebSocket.Server({ port: 8081 })
    
    wss.on('connection', (ws) => {
        sckt = ws
    
    Jake Read's avatar
    Jake Read committed
        socketSend('console', 'hello client')
    
        // send current config 
        socketSend('program', modules)
    
    Jake Read's avatar
    Jake Read committed
        console.log('socket open on 8081')
        ws.on('message', (evt) => {
            socketRecv(evt)
        })
    })
    
    // through this window
    http.listen(8080, () => {
        console.log('listening on 8080 for static files')
    })
    
    
    Jake Read's avatar
    Jake Read committed
    // server globals 
    
    
    Jake Read's avatar
    Jake Read committed
    var modules = new Array()
    
    
    // wrap require() up, appending path used to object, and giving ID
    // use the same to load from browser 
    var termOne = addModule('./src/ui/terminal.js')
    var termTwo = addModule('./src/ui/terminal.js')
    
    termOne.outputs.lineOut.attach(termTwo.lineIn)
    
    console.log(modules)
    
    
    Jake Read's avatar
    Jake Read committed
    function socketSend(type, data) {
    
        if (sckt) {
            var msg = {
                type: type,
                data: data
            }
            sckt.send(JSON.stringify(msg))
    
    Jake Read's avatar
    Jake Read committed
    function socketRecv(evt) {
    
    Jake Read's avatar
    Jake Read committed
        var recv = JSON.parse(evt)
        var type = recv.type
        var data = recv.data
        // bang thru
    
    Jake Read's avatar
    Jake Read committed
        switch (type) {
    
    Jake Read's avatar
    Jake Read committed
            case 'console':
                console.log('recv console:', data)
                break
            case 'get menu':
                var tree = buildMenu()
    
    Jake Read's avatar
    Jake Read committed
                socketSend('put menu', tree)
                break
            case 'add module':
                addModule(data)
                break
            case 'put state':
                newState(data)
                break
            case 'put link':
    
    Jake Read's avatar
    Jake Read committed
                // id:output > id:input
                break
            case 'rm link':
                // id:output > id:input
    
    Jake Read's avatar
    Jake Read committed
                break
            default:
                console.log('server recv with non recognized type', recv)
                break
    
    Jake Read's avatar
    Jake Read committed
        }
    
    Jake Read's avatar
    Jake Read committed
    function addModule(path) {
        // get and add to server system
        if (fs.existsSync(path)) {
            var src = require(path) // get and return 
    
            var mod = new src() // make a new one
            modules.push(mod) // add to the system
    
            // assign and id and remember from whence it came
    
    Jake Read's avatar
    Jake Read committed
            mod.id = modules.length - 1
    
            // add hooks to external fn's
            mod.emitStateChange = onStateOutput
            console.log('adding module', mod.description.name, 'id', mod.id)
    
    Jake Read's avatar
    Jake Read committed
            // now roll and return representable object 
    
    Jake Read's avatar
    Jake Read committed
            socketSend('put new rep', mod)
    
            // also to fn call, in case writing program ? 
            return mod
    
    Jake Read's avatar
    Jake Read committed
        } else {
            console.log('no module found at', path)
        }
    }
    
    
    function onStateOutput(mod){
        socketSend('put state', mod)
    }
    
    
    Jake Read's avatar
    Jake Read committed
    function newState(data) {
    
    Jake Read's avatar
    Jake Read committed
        // should just recv all state, walk tree for differences
    
        var os = modules[data.id].state
    
    Jake Read's avatar
    Jake Read committed
        var ns = data.state
    
    Jake Read's avatar
    Jake Read committed
        var id = data.id
    
    Jake Read's avatar
    Jake Read committed
    
        for (key in os) {
    
            if (os[key] != ns[key]) {
                os[key] = ns[key]
                console.log(key, 'to ', ns[key], 'in', data.id)
                modules[data.id].onStateChange(key)
    
    Jake Read's avatar
    Jake Read committed
            }
    
    function putLink(data) {
        var fromModule = modules.find((module) => {
            return module.id === data.from.id
        })
    
        var toModule = modules.find((module) => {
            return module.id === data.to.id
        })
    
        console.log('from', fromModule)
        console.log('to', toModule)
    
        fromModule.outputs[data.from.output].attach(toModule.inputs[data.to.input])
    
        console.log('new from', fromModule)
    }
    
    
    Jake Read's avatar
    Jake Read committed
    function put(data) {
        switch (data.target) {
    
    Jake Read's avatar
    Jake Read committed
            case 'state':
                // match data.id
                // check match data.rep.state on internal
                break
            default:
                console.log('put req with no recognized type', data)
        }
    }
    
    Jake Read's avatar
    Jake Read committed
    function buildMenu() {
        var tree = {}
    
    Jake Read's avatar
    Jake Read committed
        var dir = fs.readdirSync('./src')
    
    Jake Read's avatar
    Jake Read committed
        for (i in dir) {
    
    Jake Read's avatar
    Jake Read committed
            tree[dir[i]] = {}
            var subdir = fs.readdirSync('./src/' + dir[i])
    
    Jake Read's avatar
    Jake Read committed
            for (j in subdir) {
    
    Jake Read's avatar
    Jake Read committed
                // find js files
    
    Jake Read's avatar
    Jake Read committed
                if (subdir[j].slice(-3) === '.js') {
    
    Jake Read's avatar
    Jake Read committed
                    var obj = {}
                    obj.path = './src/' + dir[i] + '/' + subdir[j]
                    tree[dir[i]][subdir[j].slice(0, -3)] = obj
                }
            }
        }
    
    Jake Read's avatar
    Jake Read committed
        return tree
    }
    
    Jake Read's avatar
    Jake Read committed
    // put