You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
apl-nuke/src/ws/handler.js

91 lines
2.6 KiB
JavaScript

const { pop } = require('../uuids')
const { channelEvents } = require('./channels')
const crud = require('./crud')
const { recvUpdate } = require('./streams')
const connections = {};
const handler = (ws, id) => {
connections[id] = {
connection: ws,
events: [],
}
ws.send(JSON.stringify({
event: 'info',
data: 'Welcome to APL Nuke v1.1.0!'
}))
ws.on('message', (msg) => handleMsg(msg, id))
ws.on('close', () => {
delete connections[id]
pop(id)
})
}
const handleMsg = async (msg, id) => {
try {
const d = JSON.parse(msg)
if (d.hasOwnProperty('subscribe') && channelEvents.indexOf(d.subscribe) !== -1) {
console.log('received sub for ', d.subscribe)
const channel = d.subscribe.split(':')[0]
connections[id].events.push(d.subscribe)
const dm = {
event: `${channel}:read`,
data: await crud[channel].getAll(),
}
if (channel === 'streams' && d.subscribe === 'streams:full') {
dm.event = 'streams:full'
dm.data = await crud[channel].getAllPop()
}
connections[id].connection.send(JSON.stringify(dm))
} else if (d.hasOwnProperty('event') && channelEvents.indexOf(d.event) !== -1) {
const ev = d.event.split(':')
const channel = ev[0]
const event = ev[1]
console.log(`received event for ${channel} with data %s`, d.data)
let dm;
switch (event) {
case 'create':
dm = await crud[channel].create(d.data)
recvUpdate(channel, dm)
fanoutMsg(channel, await crud[channel].getAll())
break;
case 'update':
dm = await crud[channel].update(d.data.id, d.data.data)
recvUpdate(channel, dm)
fanoutMsg(channel, await crud[channel].getAll())
break;
case 'delete':
await crud[channel].delete(d.data.id)
recvUpdate(channel, 'delete')
fanoutMsg(channel, await crud[channel].getAll())
break;
}
}
} catch (e) {
console.log(e)
}
}
const fanoutMsg = (channel, data) => {
Object.keys(connections).forEach( async (k) => {
if (connections[k].events.indexOf(`${channel}:read`) !== -1) {
const d = {
event: `${channel}:read`,
data,
}
connections[k].connection.send(JSON.stringify(d))
if (connections[k].events.indexOf('streams:full') !== -1) {
const m = await crud['streams'].getAllPop()
const d = {
event: 'streams:full',
data: m,
}
connections[k].connection.send(JSON.stringify(d))
}
}
})
}
module.exports = handler