By András Jankó on Wednesday, April 12, 2017 — 0 comments

WebSharper 4 beta-6 bugfix releasedCore team

Zafir.4.0.160.40-beta6 Is now available on NuGet, .vsix installers at WebSharper downloads ("Other versions" section).

Thanks to @cgravill and @amieres for submitting bug reports.

See this release on GitHub.

Fixes

  • #681 Return was missing so infinite loop was generated on a module-level let rec returning unit
  • #682 Mark arguments transformed in tail recursion optimization as mutable to avoid incorrect inlining which could result in invalid JS code
  • #680 Do not eta-reduce to expressions that has side effects so needs the closure
  • #666 Ignore duplicate references when initializing Sitelets in non-ASP.NET contexts, fail only on WS assemblies with different versions.
  • #684 Fix for JavaScript statements in Inline to not drop first statement if it was an expression
  • #685 Different Name and AssemblyName in F# does not cause errors

Improvements

  • #683 You can now opt-out of dead code elimination for SPA projects. Use <WebSharperDeadCodeElimination>False</WebSharperDeadCodeElimination> in the project file or add --dce- to the wsfsc.exe command line.
  • #686 Case test for erased unions with a case which is a plain object in JS now compiles, if there is no previous case that is also a plain object, then it gives a more specific error

Breaking changes

  • #670 By default, classes (including F# records and unions) with no methods translated to JS instance methods and having no base class are now translated not to have a prototype. JSON serializer was fixed to handle this. This is a performance optimization, but disallows type checks or inheriting from a class like this. So a new attribute Prototype was added to opt-in for generating a prototype for the type in the translation. Extra features: Prototype(false) forces the type to have no prototype, converting instance methods to static in translation.
By András Jankó on Saturday, March 25, 2017 — 0 comments

WebSharper 4 beta-6 releasedCore team

WebSharper 4 beta-6 contains updates to DOM and JQuery bindings, erased union types, JS output optimizations and fixes.

Visual Studio 2017, F# 4.1 and C# 7 support are coming soon.

Improvements

  • using FSharp.Compiler.Service 11.0.4. To have optimal compilation speeds, go to a folder in a solution at packages\Zafir.FSharp.4.0.155.11-beta6\tools and run ./runngen in PowerShell as administrator.
  • #650 Bindings to DOM have been updated to current ECMA specification
  • #652 Bindings to JQuery have benn updated to version 3.1.1
  • #660 Erased union and option types have been added to WebSharper.JavaScript namespace, named Union and Optional. These are similar to Choice and Option types of F#, but work as TypeScript's erased unions in the JS translation. Conversion functions are available under modules Optional and Union.
  • #651 output is using JavaScript strict mode
  • #550 custom structs can now be used in RPC calls
  • #644 F# unions with Constant null case can now be used in RPC calls
  • #642 Local generic functions in F# compile when the compiler does not need the type parameter for custom code generation (macros). If it does, you get an error "Macro name would use a local type parameter. Make the inner function non-generic or move it to module level and mark it with the Inline attribute"
  • #648 JavaScript code output optimizations:
    • Functions taking F# tupled or curried functions as parameters and only fully applying them (in the case of curried parameter) now translates to taking a flat JavaScript function. This means less closure creation and better performance when using functions like List.map2
    • Local F# tupled and curried functions are now converted to flat functions in JavaScript where possible
  • #649 Tail call optimization for F#:
    • let rec expressions with single or mutual recursion
    • Module or class (in default constructor) let rec expressions with single recursive function
    • Class members, calling itself but no other members of the same class annotated with JavaScript (so inlines do not opt-out of optimization). For instance members, the call must be on the current instance.
  • #655 Require and RemotingProvider attributes can take additional object parameters. These will be passed on to the constructors of the resource class and the client-side RemotingProvider instance respectively.
  • WebSharper.Resources.BaseResource is not an abstract class any more. This allows using it with the Require attribute without defining an extra type: ` fsharp [<Require(typeof<Resources.BaseResource>, "//myurl.com/mylib.js")>]`

Fixes

  • #645 Name conflict in WebSharper.Sitelets.Content from C#
  • #657 Using Name attribute on properties with getter and setter now adds set_ to the name of the setter to disambiguate them.
  • #633 WIG-defined interfaces now can be inherited from with F#/C# code if they contain only method definitions without custom inline annotations. Calling interface members from .d.ts-based bindings now translate properly, but these interfaces can't be inherited from in your code (as they are using special call semantics).
  • #665 Unpacking Scripts/Contents for web projects required the WebProjectOutputDir property, although previously assumed project root as default. This default has been restored for back-compatibility.
  • #668 Printing F# compilation errors and warnings as compiling with fsc.exe would, respecting nowarn, warn, warnon, warneserror flags
  • #667 Fix C# analyzer giving failure warnings on build
  • #669 Async.StartImmediate and Async.StartWithContinuations now start the async immediately as in .NET, possibly finishing synchronously if they contain no bind/combine.
  • #671 Fix a translation bug in optimization around calling curried instance members
  • #673 integer type Parse and TryParse methods follow .NET semantics, checking boundaries and disallowing fractions
  • #677 Fix using Inline on constructors calling into other constructors
  • #678 Fix inlining JavaScript statements, and using return to produce a value
  • #679 exception properties Message and InnerException should work for all exception types
  • #676 Queue and Stack constructors taking a seq<'T> (IEnumerable<T>)

Breaking changes

  • Macro API: MacroResult.MacroNeedsResolvedTypeArg now needs the offending type parameter as a field. You can decide if a type is a type parameter of any kind by using the new IsParameter property.

By Kimserey Lam on Wednesday, March 1, 2017 — 0 comments

Create a simple form engine with WebSharper.UI.Next in F#Community

Create a simple form engine with WebSharper.UI.Next in F# WebSharper came out with WebSharper.Forms. It is a terse DSL to build form, I posted a tutorial on it few months ago https://kimsereyblog.blogspot.co.uk/2016/03/create-forms-with-websharperforms.html. It’s very powerful as the abstraction handles most of the scenarios. Today I would like to show anothe way to create forms by building a
>> Read the full article on kimsereyblog.blogspot.com
By Kimserey Lam on Thursday, February 23, 2017 — 0 comments

Post form data to WebSharper sitelet from HTML/JSCommunity

Post form data to WebSharper sitelet from HTML/JS When building websites, chances are that you will need to gather data from your users. The most common way to gather data is via a form. But after gathering the data, there are two ways to submit it from the browser to your server: Using a HTML form Using an Ajax call Today we will see the differences and how we can implement it. 1. Submit data
>> Read the full article on kimsereyblog.blogspot.com
By Kimserey Lam on Monday, February 13, 2017 — 0 comments

Use Local storage with ListModel with WebSharper.UI.Next in F#Community

Use JS local storage with ListModel with WebSharper UI.Next in F# Last week I wanted to use the browser local storage to store a list of elements. I wanted to update the resource split project to have the data stored (temporarily) so that it will be easier to add or remove resources. The browser local storage is ideal for this kind of scenario. Turns out WebSharper.UI.Next has the feature built
>> Read the full article on kimsereyblog.blogspot.com
By Kimserey Lam on Friday, February 3, 2017 — 0 comments

How to avoid input lost focus with ListModel WebSharper F#Community

20170202_listmodel_websharper_lostfocus.md How to avoid input lost focus with ListModel WebSharper F# Few months ago, I explained how ListModel worked. Today I would like to share a recurring issue that I used to have - lost of focus on input every time the ListModel values change. There’s an easy solution to that which I will demonstrate by first showing the initial code and
>> Read the full article on kimsereyblog.blogspot.com
By Kimserey Lam on Monday, January 23, 2017 — 0 comments

Authentication for WebSharper sitelet with JWT token in F#Community

Authentication for WebSharper sitelet with Jwt token in F# Authentication is an important part of any Web applications. Today I will explain how we can create the essential modules required to authenticate a user. This post will be composed by four parts: 1. What is needed for authentication 2. Password encryption and storage 3. JWT token 4. OWIN auth middleware and WebSharper OWIN selfhost
>> Read the full article on kimsereyblog.blogspot.com
By Adam Granicz on Saturday, December 31, 2016 — 0 comments

Simple reactive scenarios with WebSharperCore team

(This post is part of F# Advent 2016 - Happy 2017!)

One of the most fundamental design considerations any developer must deal with is handling change. In this article, we are primarily concerned with client-side state and changes to it. Change can be brought about by various external factors (user input such as mouse or keyboard events, server push messages, etc.) or by means internal to the application itself.

For a long time, handling client-side changes was tied to an object-oriented, event-driven programming style that required a user-initiated action/event connected to an UI control "instance". You may remember adding event handlers for buttons that triggered an action and possibly a change in the state of the user interface by refreshing relevant controls.

While the range of events to which event handlers can be attached typically grows with the maturity (and complexity) of the encompassing UI framework (ASP.NET, WinForms, WPF, etc.), they themselves will never be enough to handle change as we would like to.

Two-way binding with reactive variables

WebSharper long introduced UI.Next to supersede WebSharper.Html as its main DOM construction library.

Buried deep in the WebSharper documentation, you can find a comprehensive tutorial on how to use UI.Next for basic two-way data binding with reactive markup. The drill is pretty simple: next to composing with ordinary HTML combinators, you can use various HTML input controls whose values are automatically synched with a reactive variable (typically of type Var<string>).

Here we have a plain input box bound to v:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
open WebSharper
open WebSharper.JavaScript
open WebSharper.UI.Next
open WebSharper.UI.Next.Html
open WebSharper.UI.Next.Client
open WebSharper.UI.Next.Notation

[<JavaScript>]
module SimpleInput =

	let Main =
	    let v = Var.Create ""
	    div [
	        Doc.Input [] v
	    ]
	    |> Doc.RunById "main"

You can now update the input box easily by writing to v. Consider the addition of a simple Clear button:

1
2
3
4
5
	    ...
		div [
	        buttonAttr [on.click (fun _ _ -> v := "")] [text "Clear"]
	        Doc.Input [] v
	    ]

The fun starts when there is dependent markup in your page computed from the value of the input box. Say, you wanted to echo what's typed into the input box, using all caps:

1
2
3
4
5
6
	    ...
        div [
            buttonAttr [on.click (fun _ _ -> v := "")] [text "Clear"]
            Doc.Input [] v
            p [textView (v.View.Map (fun s -> s.ToUpper()))]
        ]

Here, v.View returns the current value of v, and textView converts it to an HTML text node. You can also react to keyboard and mouse input (API) equally easily:

1
2
3
4
        div [
            ...
            p [textView (Input.Mouse.Position.Map (fun (x,y) -> sprintf "%d:%d" y x))]
        ]

To sum up the basics a somewhat more elaborate live snippet is below:

List models

Now that you can gather and manipulate user input via reactive variables, and reflect computed/derived values in reactive markup, you can also bind composite data in your web pages; and this is where the real fun begins. All we need is Models (API), and in particular ListModels (API).

ListModels associate values with keys in a time-varying collection. This association can be implicit, or as in most cases explicit. Below is a ListModel that stores simple names - here the names themselves act as their own key (note the id function used as the value->key map):

1
2
let names = ListModel.Create id ["John"; "James"]
names.Add "Jonathan"

Example - System messages

We are only scratching the surface here, but assume we want to display a set of system messages, each coming with one of the usual Info/Warning/Error flavor. For added complexity, we also want an Add and a Remove button to play with test data.

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
namespace Samples

open WebSharper
open WebSharper.JavaScript
open WebSharper.UI.Next
open WebSharper.UI.Next.Html
open WebSharper.UI.Next.Client
open WebSharper.UI.Next.Notation

[<JavaScript>]
module SimpleInput =
    let counter = ref 0
    let removedCounter = ref 0
    let GetNextCounter() = incr counter; !counter
    
    type MessageType = Info | Warning | Error
    type Message =
        {
            Id: int
            Title: string
            Type: MessageType
        }
        
    let RandomMessage() =
        let id = GetNextCounter()
        {
            Id = id
            Title = sprintf "Message #%d" id
            Type = if id % 3 = 0 then Info elif id % 3 = 1 then Warning else Error
        }
        
    let Main =
        let messages = ListModel.Create (fun msg -> msg.Id) [RandomMessage()]

        div [
            buttonAttr [
                on.click (fun _ _ -> messages.Add(RandomMessage()))
            ] [text "Add"]

            buttonAttr [
                on.click (fun _ _ ->
                    if !removedCounter < !counter then
                        incr removedCounter
                        messages.RemoveByKey(!removedCounter)
                )
            ] [text "Remove"]
            
            messages.View.DocSeqCached (fun msg ->
                let ty, bg =
                    match msg.Type with
                    | Info -> "info", "bg-success"
                    | Warning -> "warning", "bg-warning"
                    | Error -> "error", "bg-danger"
                pAttr [attr.``class`` bg] [text (ty + ": " + msg.Title)]
            )
        ]
        |> Doc.RunById "main"

Here, messages is initialized with a random system message, and messages.View.DocSeqCached is a fancy way of reflecting each message to markup - and note we use Bootstrap class names, so be sure to include the main Bootstrap CSS in the template you are serving for your application. A live snippet is below:

Example - Grouping system messages

Suppose that in the previous example, we want to group the system messages based on their type. We can introduce a helper function to filter the subset we are interested in:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    ...
    let Main =
        let messages = ListModel.Create (fun msg -> msg.Id) [RandomMessage()]

        let filter pred =
            messages.View.DocSeqCached (fun msg ->
                if pred msg then
                    let ty, bg =
                        match msg.Type with
                        | Info -> "info", "bg-success"
                        | Warning -> "warning", "bg-warning"
                        | Error -> "error", "bg-danger"
                    pAttr [attr.``class`` bg] [text (ty + ": " + msg.Title)] :> Doc
                else
                    Doc.Empty
            )
		...

Using filter, we can compute the info/warning/error set separately and display them after each other:

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
        let infos    = filter (fun msg -> match msg.Type with | Info    -> true | _ -> false)
        let warnings = filter (fun msg -> match msg.Type with | Warning -> true | _ -> false)
        let errors   = filter (fun msg -> match msg.Type with | Error   -> true | _ -> false)

        div [
            buttonAttr [
                on.click (fun _ _ -> messages.Add(RandomMessage()))
            ] [text "Add"]

            buttonAttr [
                on.click (fun _ _ ->
                    if !removedCounter < !counter then
                        incr removedCounter
                        messages.RemoveByKey(!removedCounter)
                )
            ] [text "Remove"]
        
            h3 [text "Info-level messages"]
            infos
            h3 [text "Warnings"]
            warnings
            h3 [text "Errors"]
            errors
        ]
        |> Doc.RunById "main"

So with a few lines adjustment we have message grouping under control - feel free to play with the live snippet below:

Conclusion

In this brief article, we looked at a few basic reactive scenarios with WebSharper and saw how UI.Next makes it easy to work with two-way binding, reactive markup, and aggregate client-side models. In upcoming articles, I will further examine ListModels and their more advanced capabilities, including client-side and client-server persistence.

Happy 2017 and happy coding!

By Kimserey Lam on Friday, December 23, 2016 — 0 comments

Output logs in Console, File and Live stream for your WebSharper siteletCommunity

Output logs in Console, File and Live stream for your WebSharper sitelet Logs are an important part of development. Extracting and analysing debug output and errors is very important especially when the web server goes live. In this post I will show how we can setup a Console target, a File target and a Live stream on a static HTML page using NLog. NLog is a log framework which can be configured
>> Read the full article on kimsereyblog.blogspot.com
By András Jankó on Wednesday, December 7, 2016 — 0 comments

The road to WebSharper 4Core team

We started work on WebSharper 4 more than a year ago, open-sourced it in May and published first beta packages in August. It is a project with a big scope and still some features are planned before we would call it stable. This article is an introduction and also a status report.

What is WebSharper 4?

WebSharper is a toolset consisting of a .NET-to-JavaScript compiler, web framework and libraries. WebSharper 4 adds support for tranlating C# and expands F# language and .NET main library coverage for client-side availability. Main features are:

  • Write client and server code in a single language, or now with a mix of C# and F#. Communication between the client and server is transparent and type-safe.
  • You can also specify exact translation of method with attributes, this JavaScript code is checked for validity at compile-time or in code service.
  • Lightweight JavaScript runtime and generated code. Simple .NET types translate to JavaScript built-in types. No reflection support and some types cannot be checked against in client-side code but these give compile-time warnings or errors.
  • Metaprogramming: compile-time type information is used to generate output. Generating or transforming output code with custom logic is also possible with just a type definition and an attribute.

What is currently available?

WebSharper 4 beta packages are available under the codename Zafir on NuGet. Go to try.websharper.com to explore, write, test and share code snippets and mini-applications easily in both C# and F#. New documentation is under work, hosted on GitHub and browsable at websharper.com/docs. First full tutorial for C# newcomers presents a small CRUD application.

Releases

You can find previous change log of all beta releases on GitHub: beta1, beta2, beta3, beta3-bugfix, beta4, beta5.

Current vsix installers are available under Downloads in the "Other versions" section and here: Zafir.FSharp.vsix, Zafir.CSharp.vsix

New features

  • C#-to-JavaScript compiler fully compatible both ways with F# libraries. Code analyzer for giving you WebSharper-specific warnings and errors as you type.
  • Many new .NET framework features are usable client-side, including delegates, Tasks (usable for remote calls too), Linq methods.
  • Code dependency exploration for smaller output for single-page applications, with optional source mapping.

Track new releases on GitHub.

F#-specific new features

  • Not relying on ReflectedDefinition produces smaller .dll files and have improved compilation running time. JavaScript attribute now can be set on assembly level too, [<JavaScript(false)>] can remove a member or type from the compilation scope.
  • All F# language features are now supported, including object expressions, byref and & operator, inner generic functions, pattern matching on arrays, statically resolved type parameters.
  • Correct object-oriented behavior in JavaScript translation. WebSharper now fully supports method overrides, interface implementations, static constructors, base calls, constructor chaining, having no implicit constructor, self identifier on constructors.
  • Module let values now work as in .NET, not all initialized in arbitrary order on page load, only on first access of a value from a single file.
  • Better error reporting, translation failures are reported at the exact location of the expression.

For upgrading your WebSharper 3 projects, check out the update guide.

The future

There are a couple major features planned for the final release sometime in 2017, and also general quality improvements like API cleanup, more documentation and tutorials.

Planned features

  • C# 7 and F# 4.1 support. These include better interoperability between the two languages (newly added implicit conversions) which would simplify using from C# even those libraries in the WebSharper ecosystem or older projects which were not updated by hand to have C#-friendly overloads.
  • Support for .NET Core by the WebSharper server runtime and libraries.
  • TypeScript interoperability, including a code generator to generate C# or F# code from .d.ts, and .d.ts output for WebSharper projects.

Planned optimizations

  • Generated code optimizations for performance. For example transforming curried and tupled F# function arguments into multi-argument functions. The proxies for standard .NET classes are implemented in F# in WebSharper, so less function object creation by them would benefit C# WebSharper projects too.
  • Compiler and server runtime performance. For example better metadata format that allows partial deserialization which would reduce compiler running time and server startup time.
  • More .NET coverage, including client-side support for collection interfaces like IDictionary and better translation of type checks and conversions of value types.

Feedback and questions are welcome at the WebSharper forums and issue reports on GitHub.

Happy coding!