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!

By András Jankó on Wednesday, December 7, 2016 — 1 comment

Distributed web applications in F# with WebSharperCore team

This article is part of F# Advent 2016

Introduction

Often some functionality of a web application is split between the server and client layers. For example you want a separate component on the page which needs server interaction and package it to reuse in multiple projects. Sometimes you need to talk to the server to be which is hosting the current application, sometimes another one that hosts a service for multiple web applications.

We will look at the tools that WebSharper provides to achieve all this and some more using only F#.

There is just a fresh release of WebSharper 4 beta out which contains fixes for these features, be sure to grab Zafir beta-5 packages from NuGet or get the Visual Studio installer for project templates here. For a short introduction, read The road to WebSharper 4.

WebSharper remoting

We will go into a couple new features of WebSharper 4 beta later, but start with a long-time basis of WebSharper: RPCs. Just having a Remote annotated method exposes it to be callable from client-side code which is translated to JavaScript:

1
2
3
4
5
6
7
8
9
10
[<Remote>] // runs on the server
let GetData key = async { return DataStore.[key] } 

[<JavaScript>] // runs in the browser
let DataView key =
	async { 
		let! data = GetData key // calls server asynchronously
		return div [ text data ] // creates the view when response has arrived
	} |> Doc.Async // converts to an `Async<Doc>` to `Doc` value that can be embedded
				   // on a page and displays content as soon as it is available

This is transparent and lightweigth way of communicating with the server, no larger state is sent back to the server, only what you explicitly pass and a user session cookie.

Let's take a look at what is happening here behind our backs:

  • The client-side gets constructs an instance of a "RemotingProvider" object. By default it is the AjaxRemotingProvider defined in WebSharper.
  • The Async method of the RemotingProvider is called with with the RPC method handle (auto-generated) and arguments. There are separate functions for calling Rpcs that return an async a Task and unit, but all use a method AsyncBase for common logic. The method handle is something like MyApp:MyApp.Server.GetData:-1287498065, containing the assembly name, full path of method and a hash of the method's signature.
  • The default implementation of AsyncBase sends a XMLHttpRequest to the client with the JSON-serialized form of the arguments.
  • Server handles the request: looks up the method based on the handle, deserializes the arguments to .NET values and executes the method.
  • Server serializes result based on metadata information which tells how they are represented in the JavaScript translation, and sends this back in the response.
  • Client deserializes JSON response into objects and applies prototypes.
  • Async continuation is called, or in case of a server error, the Error value will be propagated as in the async workflow.

So calling a remote is not a safe operation as it can throw an exception, but we can catch it:

1
2
3
4
5
6
7
8
	async {  
		try 
			let! data = GetData key 
			return div [ text data ]  
		with e ->
			Console.Log("GetData error:", e)
			return div [ text "Error" ]
	} |> Doc.Async

But it is a not a nice functional approach to rely on exceptions. There is a way to catch the error around every RPC call automatically.

Customizing the client request

We can inherit from the default AjaxRemotingProvider and override the AsyncBase member which is has the common logic to handle calling RPC methods :

1
2
3
4
5
6
7
8
9
[<JavaScript>]
type SafeRemotingProvider() =
    inherit Remoting.AjaxRemotingProvider()

	override this.AsyncBase(handle, data) =
        async.TryWith(base.AsyncBase(handle, data), 
            fun e -> 
                Console.Log("Remoting exception", handle, e)
                async.Return(box None)

This does not knows about the RPC method is actually returning, so it is just assuming that it is an option so None is a correct value. So we still need to be a bit careful to apply it only to Remote methods which are indeed returning an option.

1
2
3
4
5
6
7
[<Remote; RemotingProvider(typeof<SafeRemotingProvider>)>]
let GetData key =
    async { 
		match DataStore.TryGetValue(key) with 
		| true, c -> return Some c
		| _ -> return NOne
	} 

A good practice would be to have all RPC methods return an option (or Result or similar union) value and use the RemotingProvider attribute on the module defining the server-side functions, or even on assembly level.

Setting the target server

The default AsyncBase looks up the Endpoint property on the same object, which by default reads a module static value WebSharper.Remoting.Endpoint. This gives us a couple possibilities:

  • If we want all remoting to target a server with a known URL, we can just set WebSharper.Remoting.Endpoint in the client side startup.
  • If we want to host some server-side functionality as a separate service used by multiple web applications, we can put the it in a library project and apply a custom RemotingProvider class for the assembly that overrides the Endpoint property. You can use the WebSharper.Web.Remoting.AddAllowedOrigin method on server startup to allow access to the RPCs from other origins (sites which will be using your service).

Decouple server-side implementation

WebSharper allows a fully type-checked communication between your web appication server and client code but if you have it all in one project then there is more coupling between the two layers than desired. It comes in handy to define your RPC methods on abstract classes so that you can implement it in another project. Then you can have your communication protocol defined in a common project referenced by a server-side and client-side project not depending directly on each other.

1
2
3
4
5
namespace Model
[<AbstractClass>]
type ServerDataStore() =
	[<Remote>]
	abstract GetData : string -> Async<option<string>>

Note that now we are putting the Remote attribute on an instance method. There is no restriction on how many Remote methods you can have on a class, and you can mix abstract and non-abstract members of course. In another project we can implement this with a subclass, its methods do not need the Remote attribute as they are not directly exposed but will be called through its virtual slot.

1
2
3
4
5
6
7
8
9
type ServerDataStoreImpl(store: Dictionary<string, string>) = 
	inherit Model.ServerDataStore()
	
	override this.GetData(key) =
		async { 
			match store.TryGetValue(key) with 
			| true, c -> return Some c
			| _ -> return NOne
		}

Then we need to provide the server runtime at startup with an instance of the ServerDataStore class, which will execute its implementations of the abstract remote methods:

1
2
3
    let store = Dictionary()
    store.Add("greeting", "Hello world!")
	AddRpcHandler typeof<Model.ServerDataStore> (ServerDataStoreImpl(store))

There should be only one handler object per type. As now the RPC is an instance method, we need a small helper to call it from the client code:

1
2
3
4
	async {
		let! greet = Remote<Model.ServerDataStore>.GetData("greeting")
		greet |> Option.iter Console.Log
	}

Putting it together

These features are all combinable. So you can write a library that houses both server-side and client-side functionality for a feature, customize what happens on the client when the application calls one of the RPCs, and make the implementation of some or all RPCs overridable. We are using these possibilities actively in our current projects, we hope that WebSharper can bring joy to even more developers in the future.

By Kimserey Lam on Monday, August 29, 2016 — 0 comments

Bring internationalization (i18n) to your WebSharper webapps in FSharpCommunity

Bring internationalization (i18n) to your WebSharper webapps in FSharp When working on webapps which need to be used by international clients, it is important to provide internationalization (i18n). I18n is the process of developing web/desktop/mobile applications which provide an easy way to change language and culture to be localized to different markets. For example, English and French markets
>> Read the full article on kimsereyblog.blogspot.com
By Kimserey Lam on Tuesday, August 2, 2016 — 0 comments

Create HTML componants for your WebSharper webapp with UI.Next templateCommunity

Create HTML componants for your WebSharper webapp with UI Next template WebSharper.UI.Next comes with a simple template engine which can be used to build doc elements. It is built using a F# typeprovider therefore gives typesafety for templating. If you never used WebSharper or WebSharper.UI.Next before, I published a tutorial few months ago on how WebSharper works and how you can use it to
>> Read the full article on kimsereyblog.blogspot.com
By Kimserey Lam on Tuesday, July 19, 2016 — 0 comments

How to setup a nice output folder for WebSharper projectsCommunity

How to setup a nice output folder for WebSharper projects There are part of software development which aren’t very exciting. Setting up output directories is one of them. But we have to go through it because having a well defined output structure helps tremendously when time comes to deploy and publish an application. When using the default template from WebSharper, it could be confusing how and
>> Read the full article on kimsereyblog.blogspot.com
By Kimserey Lam on Tuesday, July 5, 2016 — 0 comments

From idea to product with WebSharper in FSharpCommunity

From idea to product with WebSharper in FSharp From time to time I get asked, Why do you use WebSharper? A legitimate question as from the abundance of libraries, tools and frameworks available, one might think that WebSharper + F# is just another hippie stack. My answer to this question is: What matters isn’t the tools that you use but the products that you build with those tools WebSharper
>> Read the full article on kimsereyblog.blogspot.com
By Frank Joppe on Monday, June 27, 2016 — 0 comments

Three is a crowd – Actor basedCommunity

I was asked to give a presentation at work about Akka.Net. Even though my audience is 100% C# loving, I will give a demonstration with F# code. I was already working on a project to rewrite “Three is a Crowd” to the Actor model in F#, and this presentation was a driver to finish this project. Let’s share my experiences with Akka.Net here.Choices and MotivationThere were two goals of rewriting the game to Akka.Net. First of all, I wanted to try out a few design patterns. Secondly, if you ru [...[...]
>> Read the full article on fjoppe.weebly.com
By Kimserey Lam on Tuesday, June 21, 2016 — 0 comments

Keep your UI framework up to date for your WebSharper SPA with Paket GitHub dependenciesCommunity

Keep your UI framework up to date for your WebSharper SPA with Paket GitHub dependencies Have you ever been guilty of referencing Bootstrap in your web app just to use one feature (like the navbar for example)? Hunting for the most full featured CSS/JS UI framework for hours. Referencing a huge framework just to use one or two features. Bootstrap, Foundation, MUI or Materialize, there are so many
>> Read the full article on kimsereyblog.blogspot.com