const uuid = require('node-uuid'); const Emitter = require('component-emitter'); const crosstab = require('crosstab'); const values = require('lodash.values'); const actions = require('./state/actions'); const emitter = module.exports = new Emitter(); let isMaster = crosstab.util.tabs['MASTER_TAB'].id === crosstab.id; const bridge = new Map(); const { updatePrinters, updateWorkerId } = actions; const printers = { '1': { id: '1', name: 'Main printer', lock: '' }, '2': { id: '2', name: 'Handled printer', lock: '' } }; const handlers = { 'PRINT': (action, fn) => { fn(); }, 'LOCK_PRINTER': (action, fn) => { const alreadyLocked = values(printers).filter((printer) => { return printer.lock === action._origin; }); alreadyLocked.forEach((printer) => { printers[printer.id] = { ...printers[printer.id], lock: '' }; }); printers[action.payload] = { ...printers[action.payload], lock: action._origin }; fn(); } }; crosstab.util.events.on('message', ({ data, origin }) => { if (origin === crosstab.id) { return; } if (!data || !data.type) { return; } if (!data._id) { return emitter.emit('action', data); } const b = bridge.get(data._id); if (b) { data.error ? b.reject(new Error(data.error)) : b.resolve(data.payload); return bridge.delete(data._id); } if (!handlers[data.type]) { return emitter.emit('action', data); } handlers[data.type]({ ...data, _origin: origin }, (err, res) => { crosstab.broadcast('message', { ...data, error: err && err.message }, origin); }); }); crosstab.util.events.on(crosstab.util.eventTypes.becomeMaster, () => { isMaster = true; }); crosstab.util.events.on(crosstab.util.eventTypes.demoteFromMaster, () => { isMaster = false; }); const dispatch = module.exports.dispatch = (action, tab) => { if (isMaster && !tab) { if (handlers[action.type]) { return new Promise(function(resolve, reject) { handlers[action.type]({ ...action, _origin: crosstab.id }, function(err, res) { return err ? reject(err) : resolve(res); }); }); } } const id = uuid.v4(); const then = new Promise((resolve, reject) => { bridge.set(id, { resolve, reject }); }); crosstab.broadcast('message', { ...action, _id: id }, tab); return then; }; setTimeout(function() { emitter.emit('action', updateWorkerId(crosstab.id)); }, 450); setInterval(() => { if (!isMaster) { return; } const action = updatePrinters(values(printers)); emitter.emit('action', action); dispatch(action); }, 1000);