ghcjs-websockets 0.3.0.2 → 0.3.0.3
raw patch · 8 files changed
+134/−13 lines, 8 files
Files
- CHANGELOG.md +7/−0
- README.md +10/−2
- ghcjs-websockets.cabal +9/−2
- src/JavaScript/Blob.hs +17/−4
- src/JavaScript/NoGHCJS.hs +50/−0
- src/JavaScript/WebSockets.hs +0/−2
- src/JavaScript/WebSockets/FFI.hs +29/−0
- src/JavaScript/WebSockets/Internal.hs +12/−3
CHANGELOG.md view
@@ -1,3 +1,10 @@+0.3.0.3+-------+<https://github.com/mstksg/ghcjs-websockets/releases/tag/v0.3.0.3>++* Added CPP an cabal file flags necessary to enable building on (normal)+ GHC, for hackage and usage with hybrid projects.+ 0.3.0.2 ------- <https://github.com/mstksg/ghcjs-websockets/releases/tag/v0.3.0.2>
README.md view
@@ -4,7 +4,7 @@ *ghcjs-websockets* aims to provide a clean, idiomatic, efficient, low-level, out-of-your-way, bare bones, concurrency-aware interface with minimal abstractions over the [Javascript Websockets API][jsapi], inspired by common-Haskell idioms found in libraries like [io-stream][] and the server-side+Haskell idioms found in libraries like [io-streams][] and the server-side [websockets][] library, targeting compilation to Javascript with `ghcjs`. The interface abstracts websockets as simple IO/file handles, with additional@@ -25,7 +25,7 @@ Documenation is [online on github pages][documentation]. [jsapi]: http://www.w3.org/TR/websockets/-[io-stream]: http://hackage.haskell.org/package/io-streams+[io-streams]: http://hackage.haskell.org/package/io-streams [websockets]: http://hackage.haskell.org/package/websockets [binary]: http://hackage.haskell.org/package/binary [documentation]: http://mstksg.github.io/ghcjs-websockets/JavaScript-WebSockets.html@@ -137,6 +137,14 @@ These will normally be deleted; however, you can use `closeConnectionLeftovers` or `withUrlLeftovers` to grab a list of the raw `SocketMsg`s remaining after closing.++### Issues and Roadmap++As of now, there are still some exceptions that might be thrown by the+Javascript websockets API that are not explicitly handled by the library. For+the most part, things are usable and asynchronous exceptions (in Haskell)+should all be handled well at this point. There are also some small aspects+of the websockets API that aren't yet accessible through the library. ### Copyright
ghcjs-websockets.cabal view
@@ -1,5 +1,5 @@ name: ghcjs-websockets-version: 0.3.0.2+version: 0.3.0.3 synopsis: GHCJS interface for the Javascript Websocket API description: Documentation online at@@ -90,19 +90,26 @@ type: git location: https://github.com/mstksg/ghcjs-websockets +flag ghcjs+ description: Tell cabal we are using ghcjs (work around until hackage supports impl(ghcjs))+ default: True+ library exposed-modules: JavaScript.WebSockets , JavaScript.WebSockets.Internal -- ghcjs-options: -O2 other-modules: JavaScript.Blob , JavaScript.WebSockets.FFI+ , JavaScript.NoGHCJS -- other-extensions: ghc-options: -Wall build-depends: base >= 4.7 && < 5 , base64-bytestring >= 1 , binary >= 0.7 , bytestring >= 0.10- , ghcjs-base >= 0.1 , text >= 1+ -- if impl(ghcjs)+ if flag(ghcjs)+ build-depends: ghcjs-base >= 0.1 hs-source-dirs: src default-language: Haskell2010
src/JavaScript/Blob.hs view
@@ -11,24 +11,37 @@ import Control.Exception (mask_) import Data.ByteString (ByteString)++#ifdef ghcjs_HOST_OS import GHCJS.Foreign (bufferByteString) import GHCJS.Types (JSRef)-+#else+import JavaScript.NoGHCJS+#endif data Blob_ type Blob = JSRef Blob_ +#ifdef ghcjs_HOST_OS foreign import javascript interruptible "var reader = new FileReader();\ reader.addEventListener('loadend', function() {\ $c(reader.result);\ });\ reader.readAsArrayBuffer($1);"- ffi_readBlob :: Blob -> IO (JSRef a)+ ffi_readBlob :: Blob -> IO (JSRef a) -foreign import javascript unsafe "$1 instanceof Blob" ffi_blobCheck :: JSRef a -> IO Bool+foreign import javascript unsafe "$1 instanceof Blob"+ ffi_blobCheck :: JSRef a -> IO Bool+#else+ffi_readBlob :: Blob -> IO (JSRef a)+ffi_blobCheck :: JSRef a -> IO Bool +ffi_readBlob = error "ffi_readBlob: only available in JavaScript"+ffi_blobCheck = error "ffi_blobCheck: only available in JavaScript"+#endif+ readBlob :: Blob -> IO ByteString readBlob b = bufferByteString 0 0 =<< mask_ (ffi_readBlob b) isBlob :: JSRef a -> IO Bool-isBlob ref = ffi_blobCheck ref+isBlob = ffi_blobCheck
+ src/JavaScript/NoGHCJS.hs view
@@ -0,0 +1,50 @@+{-# OPTIONS_HADDOCK hide #-}++module JavaScript.NoGHCJS where++data JSArray a+data JSBool+data JSObject a+data JSRef a++type JSString = String++jsTrue :: a+jsTrue = error "jsTrue: only available in JavaScript"++setProp :: a+setProp = error "setProp: only available in JavaScript"++newObj :: a+newObj = error "newObj: only available in JavaScript"++toJSString :: a+toJSString = error "toJSString: only available in JavaScript"++fromArray :: a+fromArray = error "fromArray: only available in JavaScript"++getPropMaybe :: a+getPropMaybe = error "getPropMaybe: only available in JavaScript"++fromJSBool :: a+fromJSBool = error "fromJSBool: only available in JavaScript"++newArray :: a+newArray = error "newArray: only available in JavaScript"++jsNull :: a+jsNull = error "jsNull: only available in JavaScript"++fromJSString :: a+fromJSString = error "fromJSString: only available in JavaScript"++fromJSRef :: a+fromJSRef = error "fromJSRef: only available in JavaScript"++isNull :: a+isNull = error "isNull: only available in JavaScript"++bufferByteString :: Int -> Int -> a+bufferByteString = error "bufferByteString: only available in JavaScript"+
src/JavaScript/WebSockets.hs view
@@ -42,7 +42,6 @@ , connectionCloseReason , connectionOrigin -- * Sending data- -- $sending , sendData , sendData_ , sendText@@ -52,7 +51,6 @@ , send , send_ -- * Receiving data- -- $receiving , receive , receiveMaybe , receiveText
src/JavaScript/WebSockets/FFI.hs view
@@ -23,7 +23,12 @@ ) where import Data.Text (Text)++#ifdef ghcjs_HOST_OS import GHCJS.Types (JSRef, JSArray, JSString, JSObject, JSBool)+#else+import JavaScript.NoGHCJS+#endif data Socket_ type Socket = JSRef Socket_@@ -38,6 +43,7 @@ type WSCloseEvent = JSObject () +#ifdef ghcjs_HOST_OS foreign import javascript unsafe "$1.close();" ws_closeSocket :: Socket -> IO () @@ -99,3 +105,26 @@ foreign import javascript unsafe "$1.readyState" ws_readyState :: Socket -> IO Int+#else++ws_closeSocket :: Socket -> IO ()+ws_socketSend :: Socket -> JSString -> IO ()+ws_handleOpen :: Socket -> IO Socket+ws_newSocket :: JSString -> ConnectionQueue -> ConnectionWaiters -> IO Socket+ws_awaitConn :: ConnectionQueue -> ConnectionWaiters -> WaiterKilled -> IO (JSRef ())+ws_clearWaiters :: ConnectionWaiters -> IO ()+ws_clearQueue :: ConnectionQueue -> IO ()+ws_handleClose :: Socket -> IO WSCloseEvent+ws_readyState :: Socket -> IO Int++ws_closeSocket = error "ws_closeSocket: only available in JavaScript"+ws_socketSend = error "ws_socketSend: only available in JavaScript"+ws_handleOpen = error "ws_handleOpen: only available in JavaScript"+ws_newSocket = error "ws_newSocket: only available in JavaScript"+ws_awaitConn = error "ws_awaitConn: only available in JavaScript"+ws_clearWaiters = error "ws_clearWaiters: only available in JavaScript"+ws_clearQueue = error "ws_clearQueue: only available in JavaScript"+ws_handleClose = error "ws_handleClose: only available in JavaScript"+ws_readyState = error "ws_readyState: only available in JavaScript"++#endif
src/JavaScript/WebSockets/Internal.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE IncoherentInstances #-}@@ -27,6 +28,7 @@ Connection(..) , SocketMsg(..) , ConnClosing(..)+ , Socket -- ** Typeclasses , WSSendable(..) , WSReceivable(..)@@ -61,9 +63,6 @@ import Data.Text.Encoding (decodeUtf8', encodeUtf8, decodeUtf8) import Data.Traversable (mapM) import Data.Typeable (Typeable)-import GHCJS.Foreign-import GHCJS.Marshal (fromJSRef)-import GHCJS.Types (JSRef, JSString, isNull) import JavaScript.Blob (Blob, isBlob, readBlob) import JavaScript.WebSockets.FFI import Prelude hiding (mapM)@@ -71,6 +70,16 @@ import qualified Data.ByteString.Base64 as B64 import qualified Data.ByteString.Base64.Lazy as B64L++#ifdef ghcjs_HOST_OS+import GHCJS.Foreign (jsTrue, setProp, newObj, toJSString+ , fromArray, getPropMaybe, fromJSBool+ , newArray, jsNull, fromJSString )+import GHCJS.Marshal (fromJSRef)+import GHCJS.Types (JSRef, JSString, isNull)+#else+import JavaScript.NoGHCJS+#endif -- | Encapsulates a (reference to a) Javascript Websocket connection. Can -- be created/accessed with either 'openConnection' or (preferably)