{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RebindableSyntax #-}
module WebSockets where
import Data.Text
import FFI
-- | WebSocket object to keep connection, handle events and sending data.
data WebSocket
-- | WebSocket event.
data WSEvent
-- | State of WebSocket
data WSState = Connecting | Open | Closing | Closed
-- | Get current url and replace 'http' with 'ws'.
getWsUrl :: Fay Text
getWsUrl = ffi "window['location']['href'].replace('http:', 'ws:').replace('https:', 'wss:')"
-- | Wrapper over '.onopen' event.
onOpen :: WSEvent -> Fay ()
onOpen = ffi "console.log('WebSocket is up and running')"
-- | Wrapper over '.onclose' event.
onClose :: WebSocket -> Fay f -> Fay ()
onClose = ffi "%1.onclose=%2"
-- | Wrapper over '.onError' event.
onError :: WebSocket -> Fay f -> Fay ()
onError = ffi "%1.onerror=%2"
-- | Get text data from event.
eventData :: WSEvent -> Fay Text
eventData = ffi "%1['data']"
-- | Wrapper over '.onMessage'
onMessage :: WSEvent -> Fay ()
onMessage = ffi "(function(e){console.log(e); console.log(e.data);})(%1)"
-- | Key function that by given URL initialize connection, starts to listen all events and ready to sending data.
websocket
:: Text -- ^ WebSocket endpoint URL;
-> (WSEvent -> Fay ()) -- ^ when connection opened ;
-> (WSEvent -> Fay ()) -- ^ when messages received;
-> (WSEvent -> Fay ()) -- ^ when errors occured;
-> (WSEvent -> Fay ()) -- ^ when connection closed.
-> Fay WebSocket
websocket = ffi "(function (){var conn = new WebSocket(%1);\
\ conn.onopen = %2, conn.onmessage = %3, conn.onerror = %4, conn.onclose = %5;\
\return conn})()"
-- FIXME: add 'USVString', 'ArrayBuffer', 'Blob', 'ArrayBufferView'
-- | Send text data over WebSocket.
sendWS :: WebSocket -> Text -> Fay ()
sendWS = ffi "%1.send(%2)"
-- | Close current connection.
close :: WebSocket -> Fay ()
close = ffi "%1.close"
-- | Get @'WebSocket'@ from @'WSEvent'@.
target :: WSEvent -> Fay WebSocket
target = ffi "%1['target']"