Select Git revision

Jake Read authored
server.js 4.65 KiB
// file system to load / look at our available modules / edit them
const fs = require('fs')
// express serves files, http makes the connection
const app = require('express')()
const http = require('http').Server(app)
// websocket does websocket
const WebSocket = require('ws')
// 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)
})
// and listening for requests here
const wss = new WebSocket.Server({ port: 8081 })
wss.on('connection', (ws) => {
sckt = ws
// say hello
socketSend('console', 'hello client')
// send current config
socketSend('program', modules)
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')
})
// server globals
var sckt = null
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)
function socketSend(type, data) {
if (sckt) {
var msg = {
type: type,
data: data
}
sckt.send(JSON.stringify(msg))
}
}
function socketRecv(evt) {
var recv = JSON.parse(evt)
var type = recv.type
var data = recv.data
// bang thru
switch (type) {
case 'console':
console.log('recv console:', data)
break
case 'get menu':
var tree = buildMenu()
socketSend('put menu', tree)
break
case 'add module':
addModule(data)
break
case 'put state':
newState(data)
break
case 'put link':
putLink(data)
// id:output > id:input
break
case 'rm link':
// id:output > id:input
break
default:
console.log('server recv with non recognized type', recv)
break
}
}
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
mod.id = modules.length - 1
mod.path = path
// add hooks to external fn's
mod.emitStateChange = onStateOutput
console.log('adding module', mod.description.name, 'id', mod.id)
// now roll and return representable object
// first to UI
socketSend('put new rep', mod)
// also to fn call, in case writing program ?
return mod
} else {
console.log('no module found at', path)
}
}
function onStateOutput(mod){
socketSend('put state', mod)
}
function newState(data) {
// of one module
// should just recv all state, walk tree for differences
var os = modules[data.id].state
var ns = data.state
var id = data.id
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)
}
}
}
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)
}
function put(data) {
switch (data.target) {
case 'state':
// match data.id
// check match data.rep.state on internal
break
default:
console.log('put req with no recognized type', data)
}
}
function buildMenu() {
var tree = {}
var dir = fs.readdirSync('./src')
for (i in dir) {
tree[dir[i]] = {}
var subdir = fs.readdirSync('./src/' + dir[i])
for (j in subdir) {
// find js files
if (subdir[j].slice(-3) === '.js') {
var obj = {}
obj.path = './src/' + dir[i] + '/' + subdir[j]
tree[dir[i]][subdir[j].slice(0, -3)] = obj
}
}
}
return tree
}
// put