Created
September 1, 2014 00:41
-
-
Save TrevorBasinger/889df1575cbb1dff3bc1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
var Future = require('data.future'); | |
var Either = require('data.either'); | |
var State = require('fantasy-states'); | |
var Tuple2 = require('fantasy-tuples').Tuple2; | |
var Tuple3 = require('fantasy-tuples').Tuple3; | |
var IO = require('fantasy-io'); | |
var Maybe = require('pointfree-fantasy/instances/maybe'); | |
var _ = require('ramda'); | |
var http = require('http'); | |
var rl = require('readline'); | |
var daggy = require('daggy'); | |
var OLens = require('fantasy-lenses').Lens.objectLens; | |
var io = require('socket.io-client'); | |
require('pointfree-fantasy').expose(global); | |
///////////////////////////////////////////////////////////////// | |
//// Application | |
//// This application runs in a loop. As notifications are posted | |
//// to the Autobeacon db, this bot will manage dispatching | |
//// notifications. | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
//// Pure Code | |
///////////////////////////////////////////////////////////////// | |
/* Lens Helpers */ | |
var get = function (lens) { return lens.get(); }; | |
var set = curry (function (obj, lens) { return lens.set (obj); }); | |
///////////////////////////////////////////////////////////////// | |
// Bot Pointed Functor | |
///////////////////////////////////////////////////////////////// | |
Bot = daggy.tagged ('config'); | |
Bot.of = function (c) { return Bot (c); }; | |
Bot.prototype.map = function (f) { return f (this.config); }; | |
///////////////////////////////////////////////////////////////// | |
// Bot Lenses | |
// idLens :: BotConfig -> Lens | |
var idLens = OLens ('id').run; | |
// roleLens :: BotConfig -> Lens | |
var roleLens = OLens ('role').run; | |
///////////////////////////////////////////////////////////////// | |
// Bot Lens Accessors | |
// setId :: id -> Bot -> Bot | |
var setId = curry (function (id) { return compose (Bot.of, set (id), map (idLens)); }); | |
// getId :: Bot -> Int | |
var getId = compose (get, map(idLens)); | |
// setRole :: role -> Bot -> Bot | |
var setRole = function (role) { return compose (Bot.of, set (role), map (roleLens)); }; | |
// getRole :: Bot -> Int | |
var getRole = compose (get, map (roleLens)); | |
// determineRole :: String -> String -> String | |
var determineRole = function (suggested, conflict) { | |
if (suggested === '') { return determineRole ('manager', conflict) } | |
if (suggested === 'manager') { if (conflict === 'manager') { | |
return determineRole ('queue', null); } } | |
if (suggested === 'queue') { if (conflict === 'queue') { | |
return determineRole ('client', null); } } | |
if (suggested === 'client') { return 'client'; } | |
return suggested; | |
} | |
// resolveConflicts :: Config -> Bot -> Bot | |
var resolveConflicts = curry (function (config, bot) { | |
if(config.id === getId (bot)) return bot; | |
var n = determineRole (getRole (bot), config.role); | |
return setRole (n) (bot); | |
}); | |
// main :: ConfigObj -> Socket.IO.Socket -> IO () | |
var main = function (config, s) { | |
var bot = Bot.of (config); | |
return IO.of (s) | |
.chain (function (socket) { | |
socket.on ('status', function (d) { bot = resolveConflicts (d, bot); }); | |
socket.on ('all', function (d) { | |
if (d.fromId !== getId (bot)) { | |
if (d.action === 'statusCheck') { socket.emit ('status', map (I, bot)); }}}); | |
socket.emit ('all', { action: 'statusCheck', fromId: getId (bot) }); | |
return IO.of () | |
}); | |
} | |
///////////////////////////////////////////////////////////////// | |
//// Impure Code | |
///////////////////////////////////////////////////////////////// | |
function randomInt (min, max) { | |
return Math.floor (Math.random() * (max - min + 1)) + min; | |
} | |
var config = { | |
id: randomInt(0, 999999), | |
role: 'manager', | |
status: '' | |
}; | |
main (config, io.connect ('http://localhost:1234')).unsafePerform(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Sorry of the delay on this. I think the
Reader
orState
monad can be used in place ofBot
. Then we can uselocal
ormodify
to update and maintain internal state.Bacon will help us model sockets in a pure way. For instance, we can get tangible streams of
status
andall
events which can be mapped over. This eliminates the need forIO
.What does the server look like? (localhost:1234). I wanted to try to play with it, but i'm struggling to dig deep without seeing it work.