New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bind form data #35
Bind form data #35
Conversation
src/Fetch.ml
Outdated
@@ -379,6 +379,29 @@ module Response = struct | |||
external clone : t = "clone" [@@bs.send.pipe: t] | |||
end | |||
|
|||
(* This belongs to XHR spec and will probably be moved to another repo in the future *) | |||
|
|||
module Blob = struct |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wonder if we need this Blob
module given that there's a type blob
above in this file.
src/Fetch.ml
Outdated
external make : unit -> t = "FormData" [@@bs.new] | ||
|
||
(* Added for React Native polyfill compatibility *) | ||
external appendObject : string -> < .. > Js.t -> unit = "append" [@@bs.send.pipe : t] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs to be restricted to a specific shape, given this comment: #14 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it looks like a specific shape, but I have no idea really. I know very little about React Native.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a funny coincidence that @yawaramin just submitted reasonml-community/bs-webapi-incubator#187 as well. I think we ought to avoid duplicating bindings and especially types, but also want to avoid bs-fetch
depending on bs-webapi
. Perhaps creating a new bs-webapi-types
project might be an idea at least? What do you think @yawaramin and @anmonteiro?
Question: what's the point of committing the lib/ directory? It only contains JS files generated by the compiler, and really pollutes the diffs.
It was useful early on when minor releases of BuckleScript randomly broke things, and when this was updated more frequently. Nowadays it's less useful, but can still be nice to review the code generation for PRs. I've caught several cases of unfortunate code generation this way, although I would probably have caught them anyway as I'm familiar enough with the code generation to know what'll produce good and bad code. Much less useful when there's as much noise as this, but I don't mind it much. PRs here are usually not very big anyway.
Huh, that's funny. The main reason I thought FormData bindings should go in Webapi is because of the I can create a binding EDIT: to clarify, I'm suggesting to put the FormData/Blob/File/Iterator bindings in bs-fetch, rather than in bs-webapi. Although tbh the Iterator bindings should really go in BuckleScript's |
I like that idea. @yawaramin feel free to push to this PR if you see fit, or otherwise open a pre-requisite PR that I can rebase over. |
If it was only From https://developer.mozilla.org/en-US/docs/Web/API/File:
So I don't think this is going to work very well long-term, and it's going to make migration later really awkward. |
Hmm, I was afraid of that. So the best scenario is to have Blob/File/Iterator/Stream in BuckleScript's |
my proposal is we keep the types for those In this case, Is that aligned with your thinking? |
I think though that a bs-fetch user would want to be able to do some operations on at least blobs. E.g. ( https://developer.mozilla.org/en-US/docs/Web/API/Body/blob ): response.blob().then(function(myBlob) {
// do something with myBlob
}); If we tell the user at this point 'to do anything with the blob you need bs-webapi', that's frustrating. Would be better to have the operations handy in bs-fetch itself. |
I think that's already the case in this library, and IMO it would be out of scope for this change. |
I would have it in a separate package to avoid depending on But as long as the types are aliased properly, I don't think it should cause any long-term problems to keep them in You're the ones actually using this though, so I'll go along with whatever you agree on. |
OK let's keep I will flesh out the implementations of This is purely out of laziness on my part, I don't want to end up with another library to extract common parts of bs-fetch and bs-webapi 😁 |
As per PR discussion, will put more fleshed-out Blob and File bindings in bs-webapi, and keep FormData bindings in bs-fetch.
If the iterator did not produce a value this time but is not finished, keep iterating.
src/Fetch.ml
Outdated
let classify t = | ||
if Js.typeof t = "string" then `String (Obj.magic t) | ||
else `File (Obj.magic t) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Obj.magic
should have both its input and output types annotated to contain it as much as possible. If this was used internally it would be completely unsound since mli
s don't apply constraints internally.
let classify t = | |
if Js.typeof t = "string" then `String (Obj.magic t) | |
else `File (Obj.magic t) | |
let classify (t: t) = | |
if Js.typeof t = "string" then | |
`String (Obj.magic t: string) | |
else | |
`File (Obj.magic t: file) |
src/Fetch.ml
Outdated
external appendObject : name:string -> value:< .. > Js.t -> ?filename:string -> unit = | ||
"append" [@@bs.send.pipe : t] | ||
|
||
external appendBlob : name:string -> value:blob -> ?filename:string -> unit = | ||
"append" [@@bs.send.pipe : t] | ||
|
||
external appendFile : name:string -> value:file -> ?filename:string -> unit = | ||
"append" [@@bs.send.pipe : t] | ||
|
||
external setObject : name:string -> value:< .. > Js.t -> ?filename:string -> unit = | ||
"set" [@@bs.send.pipe : t] | ||
|
||
external setBlob : name:string -> value:blob -> ?filename:string -> unit = | ||
"set" [@@bs.send.pipe : t] | ||
|
||
external setFile : name:string -> value:file -> ?filename:string -> unit = | ||
"set" [@@bs.send.pipe : t] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These labels seem unnecessary to me. First because it seems unlikely that anyone's going to confuse the order of name
and value
, as this is pretty obvious and consistent over any API I've ever seen in any language. Secondly, since this binds to an existing API, there's both precedent for and an expectation for it to be unlabelled to model it as closely as possible.
@glennsl thanks for the review, will address after work. |
- Annotate `classify` return type to prevent unsoundness - Remove `name` and `value` labels
src/Fetch.ml
Outdated
let classify t : [> `String of string | `File of file] = | ||
if Js.typeof t = "string" then `String (Obj.magic t) | ||
else `File (Obj.magic t) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still doesn't constrain the input argument, so you could for example do classify 42
which would return an invalid `File
value back.
let classify t : [> `String of string | `File of file] = | |
if Js.typeof t = "string" then `String (Obj.magic t) | |
else `File (Obj.magic t) | |
let classify (t: t) : [> `String of string | `File of file] = | |
if Js.typeof t = "string" then `String (Obj.magic t) | |
else `File (Obj.magic t) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will change that.
src/Fetch.ml
Outdated
external keys : t -> string Iterator.t = "keys" [@@bs.send] | ||
external values : t -> EntryValue.t Iterator.t = "values" [@@bs.send] | ||
|
||
external appendObject : string -> _ Js.t -> ?filename:string -> unit = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit nitpicky, but <..> Js.t
is more accurate than _ Js.t
. With this you could pass in an int Js.t
for examplle, which would of course be silly, but what if at some point in the future BuckleScript decides to use Js.t
to distinguish JS and OCaml semantics of something other than objects?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there will ever be any way to create a valid int Js.t
:-) BuckleScript libs written by Hongbo are also using something similar: https://bucklescript.github.io/bucklescript/api/Js.Obj.html#VALkeys (val keys : 'a Js.t -> string array
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the functions there use < .. > Js.t
, and Bob's not exactly known for his consistency. But mostly I just don't see any good reason to be deliberately vague. It's not a technical improvement, there could be issues with it in the future, and being vague doesn't generally make for better documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough, I'll change it :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Thanks both!
This is a rebase of #14 on current master, done after obtaining permission from @fakenickels.
Question: what's the point of committing the
lib/
directory? It only contains JS files generated by the compiler, and really pollutes the diffs.