elm-web-server v5.0.0
Elm Web Server
An API with Node.js-bindings for Elm WebSocket/HTTP-servers.
Warnings
This package contains no native/kernel-code - All interop with Node.js is implemented using Elm's ports-API. Modules with ports are not intended for distribution on package-managers, as they can be unreliably implemented compared to regular Elm-modules, so open an issue if you encounter problems!
Elm, along with the Elm architecture, is designed for browser-applications; This project in an experimental attempt to embed the architecture inside Node.js.
Taking the unreasonable performance implications aside, it is fun to experience Elm as a shared language between client and server, with all of it's nice properties for refactoring and extension.
Features
- A small API to hook Elm's
Platform.programintoNode/httpand/orWebsockets/wsin Node.js. - Modules for working with Http-Request/Response & WebSocket messages on the server.
- Emulation for XmlHttpRequest & WebSocket to run
elm-lang/http&elm-lang/websocketon the server.
Installation
The package is implemented using JavaScript language-features supported >= v6.13.1 of Node.js.
The package is distributed through NPM:
npm install -S elm-web-serverif you're going to use the Server.WebSocket-module, you will need to install the following package from NPM:
npm install -S wsOpen elm-package.json and expose the internal Elm-modules from the package like this:
{
...
"source-directories": [
...
"node_modules/elm-web-server/source"
]
}Take a look at the examples-directory for inspiration.
JavaScript Interface
in Node.js, assuming an Elm module named Main compiled to main.elm.js in the same directory, the API can be used as such:
const Ews = require("elm-web-server")
const Http = require("http")
const Ws = require("ws")
const App = require("./main.elm.js")
const PORT = process.env.PORT || 3000
const worker = App.Main.worker()
const server = Http.createServer(Ews.createRequestListener(worker))
Ews.attachMessageListener(worker, new Ws.Server({ server }))
Ews.attachConsoleListener(worker)
server.listen(PORT, () => {
console.log(`listening at http://localhost:${PORT}`)
})Importing elm-web-server automatically exposes XmlHttpRequest & WebSocket globally to enable server-side usage of elm-lang/http & elm-lang/websocket.
Elm Interface
There is a couple of small modules for Elm, written to facilitate some basic server-logic.
Server.Http
The HTTP-module exposes utility for working with HTTP-requests/responses.
type alias Request =
{ connection : Connection
, method : Method
, headers : List Header
, url : Url
, body : Maybe String
}type Error
= ConnectionClosed Connection
| Error Stringlisten : (Result Error Request -> msg) -> Sub msgrespondWith : (a -> String) -> Status -> List Header -> Maybe a -> Connection -> ResponserespondWithJson : Status -> List Header -> Json.Encode.Value -> Connection -> ResponserespondWithText : Status -> List Header -> String -> Connection -> ResponserespondWithNothing : Status -> List Header -> Connection -> Responsesend : Response -> Cmd msgcompareConnection : Connection -> Connection -> BoolServer.Http.Url
The Http.Url module exposes types, decoding for Http-request urls.
toLocation is helpful if you want to parse urls using evancz/url-parser, as shown in examples/routing.
type alias Url =
{ pathname : String
, search : String
}decoder : Decoder UrltoLocation :
Url
->
{ href : String
, host : String
, hostname : String
, protocol : String
, origin : String
, port_ : String
, pathname : String
, search : String
, hash : String
, username : String
, password : String
}Server.Http.Method
The Http.Method module exposes types, encoding, and decoding for Http-request methods.
type Method
= Get
| Head
| Post
| Put
| Delete
| Trace
| Options
| Connect
| Patch
| Method Stringencode : Method -> Json.Encode.Valuedecoder : Decoder MethodServer.Http.Status
The Http.Status module exposes types, encoding, and decoding for Http-request statuses.
type Status
= Ok
| Created
| Accepted
| NonAuthoritativeInformation
| NoContent
| ResetContent
| PartialContent
| MultiStatus
| AlreadyReported
| ImUsed
| MultipleChoices
| MovedPermanently
| Found
| SeeOther
| NotModified
| UseProxy
| SwitchProxy
| TemporaryRedirect
| PermanentRedirect
| BadRequest
| Unauthorized
| PaymentRequired
| Forbidden
| NotFound
| MethodNotAllowed
| NotAcceptable
| ProxyAuthenticationRequired
| RequestTimeout
| Conflict
| Gone
| LengthRequired
| PreconditionFailed
| PayloadTooLarge
| URITooLong
| UnsupporedMediaType
| RangeNotSatisfiable
| ExpectationFailed
| ImATeapot
| MisdirectedRequest
| UnprocessableEntity
| Locked
| FailedDependency
| UpgradeRequired
| PreconditionRequired
| TooManyRequests
| RequestHeaderFieldsTooLarge
| UnavailableForLegalReasons
| InternalServerError
| NotImplemented
| BadGateway
| ServiceUnavailable
| GatewayTimeout
| HTTPVersionNotSupported
| VariantAlsoNegotiates
| InsufficientStorage
| LoopDetected
| NotExtended
| NetworkAuthenticationRequired
| Status Int Stringencode : Status -> Json.Encode.Valuedecoder : Decoder StatusServer.Http.Header
The Http.Header module exposes types, encoding, and decoding for Http-request headers.
byteLength is helpful if you want to set the ContentLength-header, as shown in examples/routing.
type Header
= ContentType MimeType
| Accept (List MimeType)
| ContentLength Int
| Header String Stringtype MimeType
= TextPlain
| TextHtml
| TextCss
| ApplicationJson
| ApplicationJavascript
| MimeType Stringencode : List Header -> Json.Encode.Valuedecoder : Decoder (List Header)byteLength : String -> IntServer.WebSocket
The WebSocket-module exposes utility for working with WebSocket connections & messages.
type Message
= Connected Connection
| Disconnected Connection
| Received Connection Stringtype Error
= ConnectionClosed Connection
| FailedToSend Connection String
| Error Stringlisten : (Result Error Message -> msg) -> Sub msgsend : String -> Connection -> Cmd msgdisconnect : Connection -> Cmd msgcompareConnection : Connection -> Connection -> BoolServer.Console
The Console-module allows you to print information to the console in different formats.
log : String -> Cmd msglogError : String -> Cmd msglogWarning : String -> Cmd msg