package async_js
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
A small library that provide Async support for JavaScript platforms
Install
dune-project
Dependency
Authors
Maintainers
Sources
v0.17.0.tar.gz
sha256=6c8898b69bd5fc0c36d0bbcf5a1a5a2cb0b5deb88504cdaeb532c50b50ac1703
doc/src/async_js/http.ml.html
Source file http.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171open Core open Async_kernel open Js_of_ocaml module Opt = Js.Opt module Optdef = Js.Optdef module Response_type = struct type 'a t = 'a XmlHttpRequest.response = | ArrayBuffer : Typed_array.arrayBuffer Js.t Opt.t t | Blob : #File.blob Js.t Js.Opt.t t | Document : Dom.element Dom.document Js.t Opt.t t | JSON : 'a Opt.t t | Text : Js.js_string Js.t t | Default : string t end module Response = struct type 'response t = { code : int ; get_header : string -> string option ; content : 'response } end module Post_body = struct type t = | Blob of File.blob Js.t | Document of Dom.element Dom.document Js.t | String of string | Form_data of Form.formData Js.t end module Method_with_args = struct type t = | Get of (string * string) list | Post of Post_body.t option end type 'k with_request_args = ?headers:(string * string) list -> ?on_progress:(loaded:int -> total:int -> unit) -> ?on_upload_progress:(loaded:int -> total:int -> unit) -> url:string -> 'k let has_get_args url = Option.is_some (String.index url '?') let request ?(headers = []) ?on_progress ?on_upload_progress ~url (type resp) ~(response_type : resp Response_type.t) (method_with_args : Method_with_args.t) = let url, method_string = match method_with_args with | Get args -> url ^ (if has_get_args url then "&" else "?") ^ Url.encode_arguments args, "GET" | Post _body -> url, "POST" in let req = XmlHttpRequest.create () in req##_open (Js.string method_string) (Js.string url) Js._true; (let open Response_type in match response_type with | ArrayBuffer -> req##.responseType := Js.string "arraybuffer" | Blob -> req##.responseType := Js.string "blob" | Document -> req##.responseType := Js.string "document" | JSON -> req##.responseType := Js.string "json" | Text -> req##.responseType := Js.string "text" | Default -> req##.responseType := Js.string ""); List.iter headers ~f:(fun (name, value) -> req##setRequestHeader (Js.string name) (Js.string value)); let response : resp Response.t Or_error.t Ivar.t = Ivar.create () in req##.onerror := Dom.handler (fun _ -> Ivar.fill_if_empty response (Or_error.error_string "Network error"); Js._true); req##.ontimeout := Dom.handler (fun _ -> Ivar.fill_if_empty response (Or_error.error_string "Timeout"); Js._true); req##.onreadystatechange := Js.wrap_callback (fun _ -> match req##.readyState with | DONE -> let res = if req##.status >= 200 && req##.status < 300 then ( let%bind.Or_error content : resp Or_error.t = let get_text_contents_or_error () = Opt.case req##.responseText (fun () -> (* This case should not be entered as per the specification of XMLHttpRequest at MDN web docs, because if a request is successful, in state [DONE] and response_type [Text] or [Default], [responseText] should not be [null]. See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseText *) error_s [%sexp "No response returned despite successful request" , { code = (req##.status : int) ; status_text = (Js.to_string req##.statusText : string) }]) Result.return in let open Response_type in match response_type with | ArrayBuffer -> Ok (File.CoerceTo.arrayBuffer req##.response) | Blob -> Ok (File.CoerceTo.blob req##.response) | Document -> Ok (File.CoerceTo.document req##.response) | JSON -> Ok (File.CoerceTo.json req##.response) | Text -> get_text_contents_or_error () | Default -> Or_error.map (get_text_contents_or_error ()) ~f:Js.to_string in let get_header s = Opt.case (req##getResponseHeader (Js.bytestring s)) (fun () -> None) (fun v -> Some (Js.to_string v)) in Ok { Response.content; code = req##.status; get_header }) else Or_error.error_s [%sexp "Request failed" , { code = (req##.status : int) ; status_text = (Js.to_string req##.statusText : string) }] in Ivar.fill_if_empty response res | _ -> ()); Option.iter on_progress ~f:(fun on_progress -> req##.onprogress := Dom.handler (fun e -> on_progress ~loaded:e##.loaded ~total:e##.total; Js._true)); Optdef.iter req##.upload (fun upload -> Option.iter on_upload_progress ~f:(fun on_upload_progress -> upload##.onprogress := Dom.handler (fun e -> on_upload_progress ~loaded:e##.loaded ~total:e##.total; Js._true))); (match method_with_args with | Get _ -> req##send Js.null | Post body -> (match body with | None -> req##send Js.null | Some body -> (match body with | Blob b -> req##send_blob b | Document d -> req##send_document d | String s -> req##send (Js.some (Js.string s)) | Form_data fd -> req##send_formData fd))); Ivar.read response ;; let get ?(arguments = []) url = Deferred.Or_error.map ~f:(fun resp -> resp.content) (request ~url ~response_type:Default (Get arguments)) ;; let post ?body url = Deferred.Or_error.map ~f:(fun resp -> resp.content) (request ~url ~response_type:Default (Post body)) ;;
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>