GithubHelp home page GithubHelp logo

fable-compiler / fable-powerpack Goto Github PK

View Code? Open in Web Editor NEW
33.0 7.0 32.0 1.49 MB

Utilities for Fable apps

Home Page: http://fable.io/fable-powerpack/

License: MIT License

F# 99.00% JavaScript 0.18% HTML 0.56% Batchfile 0.04% Shell 0.21%

fable-powerpack's Introduction

fable-powerpack

Utilities for Fable apps.

ATTENTION: Modules have been published as standalone packages (see #63). Fable.PowerPack won't receive more updates.

fable-powerpack's People

Contributors

0x53a avatar akoslukacs avatar alfonsogarciacaro avatar amcguier avatar ardave avatar ed-ilyin avatar elonon avatar forki avatar fsoikin avatar inosik avatar irium avatar jgrund avatar kevinmoesker avatar mangelmaxime avatar marcpiechura avatar mvsmal avatar pauan avatar scottshingler avatar selketjah avatar tachyus-ryan avatar wastaz avatar whitetigle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

fable-powerpack's Issues

Make `Promise.catch` and `Promise.catchBind` emit "$0.then" to make it compatible with ad-hoc implementations

Currently Promise.catch and Promise.catchBind emit $1.catch($0). This is the only point where anything except then is used, and this makes PowerPack's promises incompatible with minimal implementations, such as VSCode's Thenable.

This, in turn, forces us to do a conversion (aka "wrapper") when interacting with VSCode, which could be unnecessary if only PowerPack's Promise relied solely on then, in which case just a dirty cast !!x would be sufficient.

The proposal is to make Promise.catch and Promise.catchBind emit $1.then(undefined, $0) (per the spec) instead of the current $1.catch($0).

Fetch: get response body in case of 5xx response

In case of 5xx response, exception.Message contains nothing useful:

image

image

The server is based on Akka-Http, and handler is as following:

val route: Route =
    handleExceptions(exceptionHandler) {
        path("account") {
            post {
                entity(as[AccountDto]) { account =>
                complete(...a Future that can fail...)
            }
        }
} ~ ...

val exceptionHandler = ExceptionHandler {
    case e: Exception =>
        extractUri { uri =>
            println(s"Request to $uri could not be handled normally: ${e.getMessage}")
            complete(HttpResponse(StatusCodes.InternalServerError, entity = e.getMessage))
        }
}

image

In short, what I need is get the following response body in case of 5xx response:

image

Is it possible?

JSON deserialization of postRecord response of a DU does not work as expected

CompositionalIT/SAFE-Dojo#26 details an issue that seems to be related to deserialization of response data coming back from a POST:

  1. If the data is requested via a GET, using fetchAs<'T> all works fine.
  2. If the data is requested via a POST, using postRecord returns you a Response object, which you can in turn call .json<'T> on. This works for basic records, but when the response record contains a discriminated union, the deserialization fails.
  3. You can work around this by calling .text() |> Promise.map ofJson<'T> on the response instead of .json<'T>.

What is different between json<'T> and ofJson<'T>? I would have expected both to behave in the same way, and not to fail because there's a discriminated union in the record.

The issue linked above also contains a branch with a repro of this issue (see https://github.com/CompositionalIT/SAFE-Dojo/blob/post-serialization-issue/src/Client/app.fs#L62)

Retrieving object when Promise fails.

Hi!

I'm currently working with PouchDB a JS based NoSQL browser database.
When inserting a new record I use promises:

    promise {
      let! r= db.put(o)
      return r
    }
    |> Fable.PowerPack.Promise.map(fun response -> handler (Load response))

When this fails, PouchDB sends back an object with some interesting information, for instance the error status which would allow me to create a custom handler:

image

How can I get this object using Fable.PowerPack.Promise.catch ? Is it possible?
Thanks!

Extending Date.Local?

Hi, this is a question / suggestion about adding more data to Date.Local:

  • date format string (and maybe time, date - time format strings)
  • start of week (it's Monday here, used in date picker UIs for example)

Opinions? Go for it? I guess I can do it for the current locales.

Support for node-fetch extensions?

The fetch api can be used in node via node-fetch.

node-fetch exposes the following additional request options:

follow: 20,         // maximum redirect count. 0 to not follow redirect
timeout: 0,         // req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies)
compress: true,     // support gzip/deflate content encoding. false to disable
size: 0,            // maximum response body size in bytes. 0 to disable
agent: null         // http(s).Agent instance, allows custom proxy, certificate etc.

Would it make sense to add these to RequestProperties?

If so, I can send a PR.

`Promise` doesn't provide variants of `catch` and `either` where the rejection function returns another `Promise`

According to the spec, Promise.catch(f) is sugar for Promise.then(id, f), which allows f : exn -> U2<'T, Promise<'T>>, whereas the Fable.PowerPack's current implementations only allow f : exn -> 'T.

To avoid breaking changes, I propose not to change the signatures of catch and either, but add two new functions, catchBind and eitherBind respectively:

[<Emit("$1.catch($0)")>]
let catchBind (a: Exception->Promise<'T>) (pr: JS.Promise<'T>): JS.Promise<'T> = jsNative

[<Emit("$2.then($0,$1)")>]
let eitherBind (success: 'T->'R) (fail: Exception->Promise<'R>) (pr: JS.Promise<'T>): JS.Promise<'R> = jsNative

(I'm not completely sure about the names - not a native English speaker myself - so if anyone has better ideas...)

Promise CE is executed multiple times if there are multiple subscribers

If I create and cache a promise, then it is re-executed each time I do a .then.

A reproduction is here.

In that snippet, I create a Map<string, Promise<string>>.

I would expect the promise to behave like the C# async, be executed once, and further let! to access the cached value.

Instead it behaves like the F# async and is re-executed each time.


The workaround is to do a .then(id), and cache that.

Split Fable.PowerPack in multiple packages?

Fable.PowerPack was born to provide a common set of utilities for Fable apps that weren't tied to the compiler (as it happens with Fable.Core). However it's now becoming a hotchpotch with modules that are (I believe) very rarely used. Moreover, fortunately we've now competing libraries that are well maintained and provide better solutions.

Let's say I start a project and want to use:

Besides the problem of package visibility (we need to solve this in fable-compiler/fable-compiler.github.io#32), users may wonder why they need to add the full Fable.PowerPack to use a small part of it. Technically it's not a problem, because tree-shaking will ensure that code not-used will stay out of the bundle, but PowerPack may convey the message to new users that it's an all-in solution, when currently it's not.

So the idea would be to split Fable.PowerPack modules in different packages: Fable.Promise, Fable.Fetch, etc, and let users take ownership of some modules if they want (or just let die those that are not really used). As Elmish 3 is in beta, we could also use the opportunity to replace the dependency of Fable.PowerPack.

cc @et1975 @forki @0x53A @vbfox

Something weird with type inference in promises

the following code doesn't compile (which is expected because I messed up types):

    type ImageType =
    | NoImage
    | Image of string

    let takePicture() = async { return Some "" }
    let requestImageForConfirmation () = async {
        match 1 with
        | 2 ->
            return ImageType.NoImage    
        | _ -> return! takePicture()
    }

but the same version with promises does (but should not):

    type ImageType =
    | NoImage
    | Image of string

    let takePicture() = promise { return Some "" }
    let requestImageForConfirmation () = promise {
        match 1 with
        | 2 ->
            return ImageType.NoImage    
        | _ -> return! takePicture()  // should fail here
    }

Fetch API : Fetch_types namespace

This might be subjective, but according to certain API design guidelines, API namespace should include all the types required to work with it.

Currently I have to include Fetch_types to do anything useful with Fetch API, which perhaps shouldn't be necessary?

Documents required.

A little document to do simple things would be good. As Fable is reaching 1.0 and not everyone like to read test cases. I guess document will surely help.

Fetch makes GET request first if called with POST method in case of redirect

let props =
    [ RequestProperties.Method HttpMethod.POST
      requestHeaders [ContentType "application/json"]
      RequestProperties.Credentials RequestCredentials.Sameorigin
      RequestProperties.Body !^ body ]

GlobalFetch.fetch(RequestInfo.Url url, requestProps props)

image

The server is a Giraffe one, which makes redirect:

routef "/api/foo/%s" (fun path -> redirectTo false (sprintf "http://localhost:8090/%s" path))

It works completely fine against http://localhost:8090/... until I added the redirect.

"h" format result is incorrect for noon

Date.Format.localFormat Date.Local.englishUS "h" (DateTime(2017,8,8,12,0,0)) produces "0" instead of "12".

I can make a PR with new tests and a fix if you want.

[Regression] postRecord overrides RequestProperties in narumi

So does patch, I imagine.

The specific use case is authentication header, but it would be true for any property: the merge of passed and default properties needs to prefer passed properties and use default only if not set explicitly (I could see myself using specific content-type, for example, even if serialization method is json).

a non-beta release

Now that Fable is out of beta, PowerPack is the only "dev" release at this point that prevents me from publishing my packages as "stable" as well.

Get the response data when the server returns 400.

I have the following code:

let submitForm (model:Model) dispatch =
  fun (evt:React.FormEvent) ->
    evt.preventDefault()
    tryPostRecord "http://localhost:5000/invoices" model []
    |> Promise.bind(fun result ->
      match result with
      | Ok response ->
        response.text()
        |> Promise.map(fun url -> PostResponse.Success url)
      | Error err ->
        err.???.json<string list>()
        |> Promise.map(fun errors -> PostResponse.Errors errors)
    )
    |> Promise.map(fun (responseData) ->
      match responseData with
      | PostResponse.Success url ->
        Browser.window.location.href <- url
        ()
      | PostResponse.Errors errors ->
        (UpdateErrors errors) |> dispatch
    ) |> ignore

My server returns a bad request (400) with a json array of strings containing everything that is wrong with the model. The Error err is an exception so how do I get the response data?

Fetch with Fable 2: wrong ContentType header?

Hi,
I have been struggling to send some json data through a POST request using Fetch from a fable 2 project.

      let withProps body=
          [
              requestHeaders [ContentType "application/json"]
              RequestProperties.Mode RequestMode.Nocors
              RequestProperties.Body !!body
          ]

      let! result = 
        let props = body |> withProps
        tryPostRecord url body props

or

    let withProps body=
        [
            RequestProperties.Method HttpMethod.POST
            requestHeaders
              [
                HttpRequestHeaders.ContentType "application/json"
              ]
            RequestProperties.Mode RequestMode.Nocors
            RequestProperties.Body !!body
        ]

    body
      |> withProps
      |> fetch url
      |> Promise.bind (fun res ->
        res.text())
      |> Promise.map (Decode.fromString decoder)

However, it seems that whatever the ContentType used, it will revert to text/plain;charset=UTF-8.
I never had this problem with any of my Fable 1 projects.
So maybe I'm missing something?
Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.