elm/core-js/Signal/HTTP.js

112 lines
3.5 KiB
JavaScript
Raw Normal View History

/*! HTTP
A library for asynchronous HTTP requests (AJAX). See the
[WebSocket](http://elm-lang.org/docs/WebSocket.elm) library if
you have very strict latency requirements.
!*/
Elm.HTTP = function() {
var JS = Elm.JavaScript;
var toElmString = Elm.JavaScript.castJSStringToString;
/*[Creating Requests]*/
/** get : String -> Request String
Create a GET request to the given url.
**/
function get(url) { return request("GET")(url)(null)(["Nil"]); }
/** post : String -> String -> Request String
Create a POST request to the given url, carrying the given data.
**/
function post(url) { return function(data) {
return request("POST")(url)(data)(["Nil"]); }; }
/** request : String -> String -> String -> [(String,String)] -> Request String
Create a customized request. Arguments are request type (get, post, put,
delete, etc.), target url, data, and a list of additional headers.
**/
function request(verb) { return function(url) { return function(data) {
return function(headers) {
return {0 : "Request",
length : 1,
verb : JS.castStringToJSString(verb),
url : JS.castStringToJSString(url),
data : data === null ? null : JS.castStringToJSString(data),
headers : headers }; }; }; };
}
function registerReq(queue,responses) { return function(req) {
if (req.url !== "") { sendReq(queue,responses,req); }
};
}
function updateQueue(queue,responses) {
if (queue.length > 0) {
Dispatcher.notify(responses.id, queue[0].value);
if (queue[0].value[0] !== "Waiting") {
queue.shift();
setTimeout(function() { updateQueue(queue,responses); }, 0);
}
}
}
function sendReq(queue,responses,req) {
var response = { value: ["Waiting"] };
queue.push(response);
var request = null;
if (window.ActiveXObject) { request = new ActiveXObject("Microsoft.XMLHTTP"); }
if (window.XMLHttpRequest) { request = new XMLHttpRequest(); }
request.onreadystatechange = function(e) {
if (request.readyState === 4) {
response.value = (request.status === 200
? ["Success", toElmString(request.responseText)]
: ["Failure", request.status,
toElmString(request.statusText)]);
setTimeout(function() { updateQueue(queue,responses); }, 0);
}
};
request.open(req.verb, req.url, true);
Elm.List.map(function(pair) {
request.setRequestHeader(
JS.castStringToJSString(pair[1]),
JS.castStringToJSString(pair[2]));
})(req.headers);
request.send(req.data);
return null;
}
/*[Responses]*/
/** data Response a = Waiting | Success a | Failure Int String
The datatype for responses. Success contains only the returned message.
Failures contain both an error code and an error message.
**/
/*[Sending Requests]*/
/** send : Signal (Request a) -> Signal (Response String)
Performs an HTTP request with the given requests. Produces a signal
that carries the responses.
**/
function send(requests) {
var responses = Elm.Signal.constant(["Waiting"]);
var sender = Elm.Signal.lift(registerReq([],responses))(requests);
function f(x) { return function(y) { return x; } }
2013-01-30 11:54:09 +00:00
return Elm.Signal.lift2(f)(responses)(sender);
}
/** sendGet : Signal String -> Signal (Response String)
Performs an HTTP GET request with the given urls. Produces a signal
that carries the responses.
**/
return {get : get,
post : post,
request : request,
send : send,
sendGet : function(urls){return send(Elm.Signal.lift(get)(urls));}
};
}();