Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fixes for MovieDatabase and WorldBank #31

Merged
merged 1 commit into from

2 participants

Tomas Petricek Zach Bray
Tomas Petricek
Collaborator

This adds the second sample from my TechMesh talk (together with wrapper for experimental "apiary.io" type provider).

  • The Highcharts.d.ts file contains new "method" for some types, which needs to be translated to new <expr>(<expr>) and that is not currently supported. I added a workaround function named clone (it would be nice to support this somehow).

  • There is a change in Objects.fs that generates unit value when argument requires empty tuple (I hope this is the right way to do this):

    let construction = if refs = [] then Expr.Value( () ) else Expr.NewTuple(refs)
    
  • I included the "experimental" apiary.io provider in a separate FSharp.Data.Experimental package, so that is referenced (and I had to update FSharp.Data reference too).

Zach Bray ZachBray merged commit e2d8801 into from
Zach Bray
Owner

Thanks Tomas!

  • I think the new(...) methods should now be supported. It should generate a CreateInstance(...) method as a static member.
  • The change in Objects.fs looks sensible to me (at least from a quick glance). If the tests pass then it should be ok.
Tomas Petricek
Collaborator
  • Ah, I see - but I think I need something different here than create a new instance of a type. I'll post this as an issue.
  • Thanks for porting the tests to NUnit, makes it a lot easier for me (they all passed with the change)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 507 additions and 100 deletions.
  1. +6 −0 Examples/FunScript.Examples.sln
  2. +93 −0 Examples/MovieDatabase/MovieDatabase.fsproj
  3. +91 −0 Examples/MovieDatabase/Page.fs
  4. +88 −0 Examples/MovieDatabase/Web/custom.css
  5. +101 −0 Examples/MovieDatabase/Web/index.html
  6. +4 −0 Examples/MovieDatabase/packages.config
  7. +3 −0  Examples/Shared/Extensions.fs
  8. +5 −4 Examples/WorldBank/Page.fs
  9. BIN  Examples/packages/FSharp.Data.1.0.9/FSharp.Data.1.0.9.nupkg
  10. BIN  Examples/packages/FSharp.Data.1.0.9/lib/net40/FSharp.Data.dll
  11. BIN  Examples/packages/FSharp.Data.1.0.9/lib/net40/FSharp.Data.pdb
  12. BIN  Examples/packages/FSharp.Data.Experimental.1.0.1/FSharp.Data.Experimental.1.0.1.nupkg
  13. BIN  Examples/packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.Experimental.dll
  14. BIN  Examples/packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.Experimental.pdb
  15. BIN  Examples/packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.dll
  16. BIN  Examples/packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.pdb
  17. +40 −71 FunScript.Data/{Apiary.fs.exclude → ApiaryProvider.fs}
  18. +1 −0  FunScript.Data/Components.fs
  19. +7 −2 FunScript.Data/FunScript.Data.fsproj
  20. +59 −0 FunScript.Data/Utils.fs
  21. +6 −21 FunScript.Data/WorldBankProvider.fs
  22. +2 −1  FunScript.Data/packages.config
  23. +1 −1  FunScript/Objects.fs
  24. BIN  packages/FSharp.Data.1.0.6/FSharp.Data.1.0.6.nupkg
  25. BIN  packages/FSharp.Data.1.0.6/lib/net40/FSharp.Data.dll
  26. BIN  packages/FSharp.Data.1.0.6/lib/net40/FSharp.Data.pdb
  27. BIN  packages/FSharp.Data.1.0.9/FSharp.Data.1.0.9.nupkg
  28. BIN  packages/FSharp.Data.1.0.9/lib/net40/FSharp.Data.dll
  29. BIN  packages/FSharp.Data.1.0.9/lib/net40/FSharp.Data.pdb
  30. BIN  packages/FSharp.Data.Experimental.1.0.1/FSharp.Data.Experimental.1.0.1.nupkg
  31. BIN  packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.Experimental.dll
  32. BIN  packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.Experimental.pdb
  33. BIN  packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.dll
  34. BIN  packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.pdb
6 Examples/FunScript.Examples.sln
View
@@ -30,6 +30,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Canvas", "Canvas\Canvas.fsp
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Twitter", "Twitter\Twitter.fsproj", "{63EAF56E-2390-453D-BD73-B79E85CF0DE0}"
EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MovieDatabase", "MovieDatabase\MovieDatabase.fsproj", "{C743294F-BA81-473B-A9F1-D95F5356D37A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -59,6 +61,10 @@ Global
{63EAF56E-2390-453D-BD73-B79E85CF0DE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{63EAF56E-2390-453D-BD73-B79E85CF0DE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{63EAF56E-2390-453D-BD73-B79E85CF0DE0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C743294F-BA81-473B-A9F1-D95F5356D37A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C743294F-BA81-473B-A9F1-D95F5356D37A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C743294F-BA81-473B-A9F1-D95F5356D37A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C743294F-BA81-473B-A9F1-D95F5356D37A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
93 Examples/MovieDatabase/MovieDatabase.fsproj
View
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{c743294f-ba81-473b-a9f1-d95f5356d37a}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <RootNamespace>FunJS.Example</RootNamespace>
+ <AssemblyName>MovieDatabase</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <Name>MovieDatabase</Name>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <Tailcalls>false</Tailcalls>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <WarningLevel>3</WarningLevel>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DocumentationFile>bin\Debug\FunJS.Example.XML</DocumentationFile>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <Tailcalls>true</Tailcalls>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <WarningLevel>3</WarningLevel>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DocumentationFile>bin\Release\FunJS.Example.XML</DocumentationFile>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup>
+ <MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
+ </PropertyGroup>
+ <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets" Condition=" Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')" />
+ <ItemGroup>
+ <None Include="Web\index.html">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
+ <None Include="Web\custom.css">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
+ <Compile Include="..\Shared\Launcher.fs">
+ <Link>Shared\Launcher.fs</Link>
+ </Compile>
+ <Compile Include="..\Shared\Extensions.fs">
+ <Link>Shared\Extensions.fs</Link>
+ </Compile>
+ <Compile Include="Page.fs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Reference Include="FSharp.Data">
+ <HintPath>..\packages\FSharp.Data.1.0.9\lib\net40\FSharp.Data.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="FSharp.Data.Experimental">
+ <HintPath>..\packages\FSharp.Data.Experimental.1.0.1\lib\net40\FSharp.Data.Experimental.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="FunScript">
+ <HintPath>..\..\FunScript\bin\Debug\FunScript.dll</HintPath>
+ </Reference>
+ <Reference Include="FunScript.Data">
+ <HintPath>..\..\FunScript.Data\bin\Debug\FunScript.Data.dll</HintPath>
+ </Reference>
+ <Reference Include="FunScript.TypeScript">
+ <HintPath>..\..\FunScript.TypeScript\bin\Debug\FunScript.TypeScript.dll</HintPath>
+ </Reference>
+ <Reference Include="FunScript.TypeScript.Interop">
+ <HintPath>..\..\FunScript.TypeScript.Interop\bin\Debug\FunScript.TypeScript.Interop.dll</HintPath>
+ </Reference>
+ <Reference Include="mscorlib" />
+ <Reference Include="FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Numerics" />
+ </ItemGroup>
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
91 Examples/MovieDatabase/Page.fs
View
@@ -0,0 +1,91 @@
+[<ReflectedDefinition>]
+module Program
+
+open FunScript
+open FSharp.Data
+
+// ------------------------------------------------------------------
+// Initializataion
+
+type MovieDb = ApiaryProvider<"themoviedb">
+
+type j = TypeScript.Api<"../Typings/jquery.d.ts">
+let jQuery (command:string) = j.jQuery.Invoke(command)
+let (?) jq name = jQuery("#" + name)
+
+type System.Object with
+ member x.asJQuery() : j.JQuery = unbox x
+
+// ------------------------------------------------------------------
+// Main function
+
+let main() =
+
+ let db = new MovieDb("http://api.themoviedb.org")
+ db.AddQueryParam("api_key", "6ce0ef5b176501f8c07c634dfa933cff")
+ let root = "http://cf2.imgobject.com/t/p/w92/"
+
+ // ----------------------------------------------------------------
+ // Show details
+
+ let showDetails (id:int) = async {
+ let! movie = db.Movie.AsyncGetMovie(id.ToString())
+ jQuery?dialogOverview.text(movie.Overview) |> ignore
+ jQuery?dialogTitle.text(movie.Title) |> ignore
+ jQuery?dialogImage.attr("src", root + movie.PosterPath) |> ignore
+
+ let! casts = movie.AsyncCasts()
+ let sorted = casts.Cast |> Array.sortBy (fun c -> c.Order)
+ let sorted =
+ if sorted.Length <= 10 then sorted |> Seq.ofArray
+ else sorted |> Seq.ofArray |> Seq.take 10
+
+ jQuery?dialogCast.html("") |> ignore
+ for cast in casts.Cast do
+ let html = "<strong>" + cast.Name + "</strong> (" + cast.Character + ")"
+ let li = jQuery("<li>")
+ li.html(html) |> ignore
+ li.appendTo(jQuery?dialogCast) |> ignore }
+
+ // ----------------------------------------------------------------
+ // Movie search
+
+ let search term = async {
+ let! res = db.Search.AsyncMovie(query=["query", term])
+ jQuery?results.html("") |> ignore
+
+ res.Results
+ |> Seq.ofArray
+ |> Seq.iteri (fun index item ->
+ let link =
+ jQuery("<a>").attr("data-toggle", "modal").asJQuery().
+ attr("href", "#detailsDialog").asJQuery().text(item.Title).asJQuery().
+ click(fun _ -> showDetails item.Id |> Async.StartImmediate ).asJQuery()
+
+ let details = jQuery("<ul>")
+ jQuery("<li>").html("<strong>Released:</strong> " + item.ReleaseDate).
+ asJQuery().appendTo(details) |> ignore
+ jQuery("<li>").html("<strong>Average vote:</strong> " + item.VoteAverage.ToString()).
+ asJQuery().appendTo(details) |> ignore
+ jQuery("<li>").html("<strong>Popularity:</strong> " + item.Popularity.ToString()).
+ asJQuery().appendTo(details) |> ignore
+
+ let body = jQuery("<div>").addClass("searchResult").asJQuery()
+ jQuery("<h3>").append([| box link |]).asJQuery().appendTo(body) |> ignore
+ jQuery("<img>").attr("src", root + item.PosterPath).asJQuery().appendTo(body) |> ignore
+ details.appendTo(body) |> ignore
+ jQuery("<div>").addClass("clearer").asJQuery().appendTo(body) |> ignore
+ body.appendTo(jQuery?results) |> ignore )}
+
+ // ----------------------------------------------------------------
+ // Movie search
+
+ jQuery?searchButton.click(fun () ->
+ let id = jQuery?searchInput.``val``() :?> string
+ search id |> Async.StartImmediate )
+
+// ------------------------------------------------------------------
+let components =
+ FunScript.Interop.Components.all @
+ FunScript.Data.Components.DataProviders
+do Runtime.Run(components=components, directory="Web")
88 Examples/MovieDatabase/Web/custom.css
View
@@ -0,0 +1,88 @@
+@import url(http://fonts.googleapis.com/css?family=News+Cycle:400);
+
+body {
+ font-family: 'News Cycle', sans-serif;
+ padding-top: 0px;
+ padding-bottom: 40px;
+}
+.masthead {
+ overflow: hidden;
+}
+.masthead ul, .masthead li {
+ margin-bottom:0px;
+}
+.masthead .nav li {
+ margin-top: 10px;
+}
+.masthead h3 {
+ margin-bottom:10px;
+ font-size:150%;
+}
+hr {
+ margin:0px 0px 0px 0px;
+}
+
+.jumbotron h1 {
+ font-size:220%;
+}
+.jumbotron p {
+ font-size:130%;
+}
+
+h2 {
+ font-size:200%;
+}
+
+.well-small h2 {
+ font-size:150%;
+}
+
+.btn {
+ border-radius: 0px;
+}
+
+input.no-margin {
+ margin-bottom:0px;
+}
+
+h3 {
+ font-size:120%;
+ line-height:normal;
+}
+
+.searchResult {
+ float:left;
+ width:33%;
+ height:200px;
+}
+
+.searchResult img {
+ float: left;
+}
+
+.searchResult ul {
+ margin-left:120px;
+}
+
+.mainclearer {
+ clear:both;
+ height:40px;
+}
+
+.searchResult .clearer {
+ clear:both;
+ height:20px;
+}
+
+#detailsDialog img {
+ float:left;
+ margin:0px 10px 10px 0px;
+}
+
+#detailsDialog .divDialogElements h3 {
+ clear:both;
+ margin-top:10px;
+}
+#results {
+ min-height:300px;
+}
101 Examples/MovieDatabase/Web/index.html
View
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Searching The Movie Database with F#</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="description" content="">
+ <meta name="author" content="Tomas Petricek">
+
+ <script src="http://code.jquery.com/jquery-1.8.0.js"></script>
+ <script src="http://code.jquery.com/ui/1.8.23/jquery-ui.js"></script>
+ <script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js"></script>
+ <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrap-combined.min.css" rel="stylesheet">
+
+ <link href="custom.css" rel="stylesheet" type="text/css" />
+ <script src="moviedatabase.js"></script>
+
+ <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
+ <!--[if lt IE 9]>
+ <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ </head>
+
+ <body>
+
+ <div class="container">
+
+ <div class="masthead">
+ <ul class="nav nav-pills pull-right">
+ <li><a href="http://fsharp.org">fsharp.org</a></li>
+ <li><a href="https://github.com/ZachBray/FunScript">funscript</a></li>
+ <li><a href="http://apiary.io">apiary.io</a></li>
+ <li><a href="http://themoviedb.org">themoviedb.org</a></li>
+ </ul>
+ <h3 class="muted">Movie Database</h3>
+ </div>
+
+ <hr>
+
+ <div class="jumbotron">
+ <h1>Searching The Movie Database with F#</h1>
+ <p class="lead">
+ Calling the Movie Database REST API using an F# type provider that generates types based on the apiary.io specification,
+ compiled using the FunScript F# to JavaScript compiler with a type provider for TypeScript definitions.
+ Enter text to search for:
+ </p>
+ </div>
+
+ <div class="row">
+ <div class="span2"></div>
+ <div class="span8">
+ <div class="well well-small hpBanner">
+ <h2>Search movies</h2>
+ <div class="input-append" style="position:relative;padding-right:180px;">
+ <input type="text" class="no-margin" id="searchInput" style="width:100%" />
+ <div class="btn-group">
+ <button class="btn" style="width:140px" id="searchButton">Search movies</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="span2"></div>
+ </div>
+
+
+ <div class="modal hide fade" id="detailsDialog">
+ <div class="modal-header">
+ <a href="#" class="close" data-dismiss="modal">&times;</a>
+ <h3 id="dialogTitle"></h3>
+ </div>
+ <div class="modal-body">
+ <div class="divDialogElements">
+ <img id="dialogImage" />
+ <p id="dialogOverview">
+ </p>
+ <h3>Cast</h3>
+ <ul id="dialogCast">
+ </ul>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <a href="#" class="btn btn-primary" onclick="$('#detailsDialog').modal('hide');">Close</a>
+ </div>
+ </div>
+
+ <h2>Found movies</h2>
+
+ <div id="results">
+ </div>
+
+ <div class="mainclearer"></div>
+ <hr />
+
+ <div class="footer">
+ <p>&copy; Tomas Petricek (<a href="http://tomasp.net">tomasp.net</a>) 2012</p>
+ </div>
+
+ </div> <!-- /container -->
+
+ </body>
+</html>
4 Examples/MovieDatabase/packages.config
View
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="FSharp.Data" version="1.0.2" targetFramework="net45" />
+</packages>
3  Examples/Shared/Extensions.fs
View
@@ -13,6 +13,9 @@ module FunScriptExtensions =
[<JS; JSEmit("return Math.floor({0});")>]
let floor (n:int) = n
+ [<JS; JSEmit("return new {0}({1});")>]
+ let clone (obj : 'T, args : 'A) : 'T = failwith "never"
+
type System.Array with
[<JS; JSEmit("return {0}.push({1});")>]
member x.push(element:obj) = ()
9 Examples/WorldBank/Page.fs
View
@@ -65,8 +65,7 @@ let main() =
let! vals = country.Indicators.``School enrollment, tertiary (% gross)``
let data = vals |> Seq.map (fun (k, v) -> [| number k; number v |]) |> Array.ofSeq
opts.series.push(h.HighchartsSeriesOptions(data=data, name=country.Name))
- // h.Highcharts.Chart.``new``(opts) |> ignore
- }
+ clone(h.Highcharts.Chart, opts) |> ignore }
// Register click handlers
render () |> Async.StartImmediate
@@ -75,5 +74,7 @@ let main() =
render() |> Async.StartImmediate |> box) |> ignore
// ------------------------------------------------------------------
-
-do Runtime.Run(components=FunScript.Data.Components.DataProviders, directory="Web")
+let components =
+ FunScript.Data.Components.DataProviders @
+ FunScript.Interop.Components.all
+do Runtime.Run(components=components, directory="Web")
BIN  Examples/packages/FSharp.Data.1.0.9/FSharp.Data.1.0.9.nupkg
View
Binary file not shown
BIN  Examples/packages/FSharp.Data.1.0.9/lib/net40/FSharp.Data.dll
View
Binary file not shown
BIN  Examples/packages/FSharp.Data.1.0.9/lib/net40/FSharp.Data.pdb
View
Binary file not shown
BIN  Examples/packages/FSharp.Data.Experimental.1.0.1/FSharp.Data.Experimental.1.0.1.nupkg
View
Binary file not shown
BIN  Examples/packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.Experimental.dll
View
Binary file not shown
BIN  Examples/packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.Experimental.pdb
View
Binary file not shown
BIN  Examples/packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.dll
View
Binary file not shown
BIN  Examples/packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.pdb
View
Binary file not shown
111 FunScript.Data/Apiary.fs.exclude → FunScript.Data/ApiaryProvider.fs
View
@@ -1,77 +1,40 @@
-module internal FunScript.ApiaryCompiler
+// --------------------------------------------------------------------------------------
+// Mappings for the Apiary Type Provider runtime
+// --------------------------------------------------------------------------------------
+
+module private FunScript.Data.ApiaryProvider
open System
+open System.Reflection
+open FSharp.Data.Json
open FunScript
open FunScript.AST
-open System.Reflection
+open FunScript.Data.Utils
+open ProviderImplementation
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.DerivedPatterns
open Microsoft.FSharp.Reflection
-open FSharp.ProviderImplementation
-
-let private undef() = failwith "!"
-
-let (|SpecificConstructor|_|) templateParameter =
- match templateParameter with
- | Patterns.NewObject(cinfo1, _) -> (function
- | Patterns.NewObject(cinfo2, args)
- when cinfo1.MetadataToken = cinfo2.MetadataToken ->
- Some(cinfo1, args)
- | _ -> None)
- | _ -> invalidArg "templateParameter" "Unrecognized quotation: Must be NewObject."
-
-[<JS; JSEmit("return {0}==null?List_Empty():{0};")>]
-let emptyIfNull (list:_ list) = list
+// --------------------------------------------------------------------------------------
+// Reimplemntation of the Apiary provider runtime
[<JS>]
module Runtime =
- open FSharp.Web
-
type ApiaryJsContext =
{ Root : string
- mutable GlobalQuery : (string * string)[] //ResizeArray<_>(queries)
- mutable GlobalHeaders : (string * string)[] //ResizeArray<_>(headers)
- mutable GlobalArguments : (string * string)[] } //arguments
- type XMLHttpRequest =
- abstract ``open`` : string * string -> unit
- abstract setRequestHeader : string * string -> unit
- abstract send : string -> unit
-
- abstract onreadystatechange : (unit -> unit) with get, set
- abstract readyState : float
- abstract responseText : string
-
- [<JSEmit("""
- var res;
- if (window.XDomainRequest) {
- res = new XDomainRequest();
- res.setRequestHeader = function (header, value) { };
- res.onload = function () {
- res.readyState = 4;
- res.status = 200;
- res.onreadystatechange();
- };
- }
- else if (window.XMLHttpRequest)
- res = new XMLHttpRequest();
- else
- res = new ActiveXObject("Microsoft.XMLHTTP");
- res.get_onreadystatechange = function() { return res.onreadystatechange; }
- res.set_onreadystatechange = function(a) { res.onreadystatechange = a; }
- res.get_readyState = function() { return res.readyState; }
- res.get_responseText = function() { return res.responseText; }
- return res;""")>]
- let newXMLHttpRequest() : XMLHttpRequest = failwith "never"
-
- [<JS; JSEmit("return encodeURIComponent({0});")>]
- let encodeURIComponent(s:string) : string = failwith "never"
+ mutable GlobalQuery : (string * string)[]
+ mutable GlobalHeaders : (string * string)[]
+ mutable GlobalArguments : (string * string)[] }
[<JS; JSEmit("{0}.get_Context = function() { return {1}; };")>]
let setContext(o:obj, ctx:obj) : unit = ()
+ [<JS; JSEmit("return {0}.get_Context();")>]
+ let getContext(o:obj) : InternalApiaryContext = failwith "never"
+
[<JS>]
type ApiaryJsRuntime =
+
static member AsyncMap(work, f) = async {
let! v = work in return f v }
@@ -125,23 +88,38 @@ module Runtime =
xhr.onreadystatechange <- (fun () ->
if xhr.readyState = 4.0 then
let source = xhr.responseText
- let doc = JsonDocument.Create(JsonParser.parse (source))
+ let doc = JsonDocument.Create(JsonValue.Parse(source))
setContext(doc, { x with GlobalArguments = allArguments } )
cont doc
)
xhr.send("")
else
failwith "Only GET supported" )
-
+// --------------------------------------------------------------------------------------
+// Define the mappings
+
open Runtime
-let private newApiaryCtx =
- <@@ new ApiaryContext(undef()) @@>
+// Deserialize the quotation for performance reasons
+let private newApiaryCtx = <@@ new ApiaryContext(undef()) @@>
+
+let components =
+ [ // ApiaryDocument behaves just like JsonDocument
+ ExpressionReplacer.createUnsafe <@ ApiaryDocument.Create @> <@ JsonProvider.JsRuntime.CreateDocument @>
+ ExpressionReplacer.createUnsafe <@ fun (d:ApiaryDocument) -> d.JsonValue @> <@ JsonProvider.JsRuntime.Identity @>
+ ExpressionReplacer.createUnsafe <@ fun (d:ApiaryDocument) -> d.Context @> <@ getContext @>
-let private apiary =
- CompilerComponent.create <| fun (|Split|) compiler returnStategy ->
+ // Apiary runtime is reimplemented by ApiaryJsRuntime
+ ExpressionReplacer.createUnsafe <@ ApiaryRuntime.ProcessParameters @> <@ ApiaryJsRuntime.ProcessParameters @>
+ ExpressionReplacer.createUnsafe <@ fun (a:ApiaryContext) -> a.AddHeader @> <@ ApiaryJsRuntime.AddHeader @>
+ ExpressionReplacer.createUnsafe <@ fun (a:ApiaryContext) -> a.AddQueryParam @> <@ ApiaryJsRuntime.AddQueryParam @>
+ ExpressionReplacer.createUnsafe <@ fun (a:ApiaryOperations) -> a.AsyncInvokeOperation @> <@ ApiaryJsRuntime.AsyncInvokeOperation @>
+ ExpressionReplacer.createUnsafe <@ ApiaryGenerationHelper.AsyncMap @> <@ ApiaryJsRuntime.AsyncMap @>
+
+ // Construction of ApiaryContext becomes just a record
+ CompilerComponent.create <| fun (|Split|) compiler returnStategy ->
function
| SpecificConstructor newApiaryCtx (_, [rootArgument]) ->
let (Split(valDecls, valRef)) = rootArgument
@@ -151,15 +129,6 @@ let private apiary =
"GlobalHeaders", Array []
"GlobalArguments", Array [] ]
[ yield! valDecls
- yield returnStategy.Return <| Object fields
- ]
+ yield returnStategy.Return <| Object fields ]
| _ -> []
-
-let components =
- [ ExpressionReplacer.createUnsafe <@ ApiaryRuntime.ProcessParameters @> <@ ApiaryJsRuntime.ProcessParameters @>
- ExpressionReplacer.createUnsafe <@ fun (a:ApiaryContext) -> a.AddHeader @> <@ ApiaryJsRuntime.AddHeader @>
- ExpressionReplacer.createUnsafe <@ fun (a:ApiaryContext) -> a.AddQueryParam @> <@ ApiaryJsRuntime.AddQueryParam @>
- ExpressionReplacer.createUnsafe <@ fun (a:ApiaryOperations) -> a.AsyncInvokeOperation @> <@ ApiaryJsRuntime.AsyncInvokeOperation @>
- ExpressionReplacer.createUnsafe <@ ApiaryGenerationHelper.AsyncMap @> <@ ApiaryJsRuntime.AsyncMap @>
- apiary
]
1  FunScript.Data/Components.fs
View
@@ -3,6 +3,7 @@
open FunScript.Data
let DataProviders =
+ ApiaryProvider.components @
JsonProvider.components @
WorldBank.components
9 FunScript.Data/FunScript.Data.fsproj
View
@@ -36,15 +36,20 @@
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets" Condition=" Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')" />
<ItemGroup>
- <None Include="Apiary.fs.exclude" />
+ <Compile Include="Utils.fs" />
<Compile Include="JsonProvider.fs" />
+ <Compile Include="ApiaryProvider.fs" />
<Compile Include="WorldBankProvider.fs" />
<Compile Include="Components.fs" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="FSharp.Data">
- <HintPath>..\packages\FSharp.Data.1.0.6\lib\net40\FSharp.Data.dll</HintPath>
+ <HintPath>..\packages\FSharp.Data.1.0.9\lib\net40\FSharp.Data.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="FSharp.Data.Experimental">
+ <HintPath>..\packages\FSharp.Data.Experimental.1.0.1\lib\net40\FSharp.Data.Experimental.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FunScript">
59 FunScript.Data/Utils.fs
View
@@ -0,0 +1,59 @@
+// --------------------------------------------------------------------------------------
+// Helper functions & JavaScript runtime for Type Provider mappings
+// --------------------------------------------------------------------------------------
+
+module private FunScript.Data.Utils
+
+open FunScript
+open Microsoft.FSharp.Quotations
+
+let undef() = failwith "!"
+
+let (|SpecificConstructor|_|) templateParameter =
+ match templateParameter with
+ | Patterns.NewObject(cinfo1, _) -> (function
+ | Patterns.NewObject(cinfo2, args)
+ when cinfo1.MetadataToken = cinfo2.MetadataToken ->
+ Some(cinfo1, args)
+ | _ -> None)
+ | _ -> invalidArg "templateParameter" "Unrecognized quotation: Must be NewObject."
+
+[<JS; JSEmit("return {0}==null?List_Empty():{0};")>]
+let emptyIfNull (list:_ list) = list
+
+type XMLHttpRequest =
+ abstract ``open`` : string * string -> unit
+ abstract setRequestHeader : string * string -> unit
+ abstract send : string -> unit
+
+ abstract onreadystatechange : (unit -> unit) with get, set
+ abstract readyState : float
+ abstract responseText : string
+
+[<JS; JSEmit("""
+ var res;
+ if (window.XDomainRequest) {
+ res = new XDomainRequest();
+ res.setRequestHeader = function (header, value) { };
+ res.onload = function () {
+ res.readyState = 4;
+ res.status = 200;
+ res.onreadystatechange();
+ };
+ }
+ else if (window.XMLHttpRequest)
+ res = new XMLHttpRequest();
+ else
+ res = new ActiveXObject("Microsoft.XMLHTTP");
+ res.get_onreadystatechange = function() { return res.onreadystatechange; }
+ res.set_onreadystatechange = function(a) { res.onreadystatechange = a; }
+ res.get_readyState = function() { return res.readyState; }
+ res.get_responseText = function() { return res.responseText; }
+ return res;""")>]
+let newXMLHttpRequest() : XMLHttpRequest = failwith "never"
+
+[<JS; JSEmit("return encodeURIComponent({0});")>]
+let encodeURIComponent(s:string) : string = failwith "never"
+
+[<JS; JSEmit("return $.getJSON({0}, {1});")>]
+let getJSON (url:string, callback : string -> unit) : unit = failwith "never"
27 FunScript.Data/WorldBankProvider.fs
View
@@ -1,8 +1,13 @@
-module private FunScript.Data.WorldBank
+// --------------------------------------------------------------------------------------
+// Mappings for the WorldBank Type Provider runtime
+// --------------------------------------------------------------------------------------
+
+module private FunScript.Data.WorldBank
open System
open FunScript
open FunScript.AST
+open FunScript.Data.Utils
open System.Reflection
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.DerivedPatterns
@@ -10,26 +15,6 @@ open Microsoft.FSharp.Reflection
type WorldBankResponse = FSharp.Data.JsonProvider<"worldbank.json">
-let private undef() = failwith "!"
-
-let (|SpecificConstructor|_|) templateParameter =
- match templateParameter with
- | Patterns.NewObject(cinfo1, _) -> (function
- | Patterns.NewObject(cinfo2, args)
- when cinfo1.MetadataToken = cinfo2.MetadataToken ->
- Some(cinfo1, args)
- | _ -> None)
- | _ -> invalidArg "templateParameter" "Unrecognized quotation: Must be NewObject."
-
-[<JS; JSEmit("return {0}==null?List_Empty():{0};")>]
-let emptyIfNull (list:_ list) = list
-
-[<JS; JSEmit("return $.getJSON({0}, {1});")>]
-let getJSON (url:string, callback : string -> unit) : unit = failwith "never"
-
-[<JS; JSEmit("return encodeURIComponent({0});")>]
-let encodeURIComponent(s:string) : string = failwith "never"
-
[<JS>]
module Runtime =
type WorldBankData =
3  FunScript.Data/packages.config
View
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="FSharp.Data" version="1.0.6" targetFramework="net40" />
+ <package id="FSharp.Data" version="1.0.9" targetFramework="net40" />
+ <package id="FSharp.Data.Experimental" version="1.0.1" targetFramework="net40" />
</packages>
2  FunScript/Objects.fs
View
@@ -72,7 +72,7 @@ let methodCallPattern (mb:MethodBase) =
yield Var(sprintf "%s_%i" var.Name i, genericArgs.[i], var.IsMutable)
]
let refs = subVars |> List.map Expr.Var
- let construction = Expr.NewTuple(refs)
+ let construction = if refs = [] then Expr.Value( () ) else Expr.NewTuple(refs)
subVars, Some (var, construction)
else failwith "Unexpected argument format"
) vars argCounts
BIN  packages/FSharp.Data.1.0.6/FSharp.Data.1.0.6.nupkg
View
Binary file not shown
BIN  packages/FSharp.Data.1.0.6/lib/net40/FSharp.Data.dll
View
Binary file not shown
BIN  packages/FSharp.Data.1.0.6/lib/net40/FSharp.Data.pdb
View
Binary file not shown
BIN  packages/FSharp.Data.1.0.9/FSharp.Data.1.0.9.nupkg
View
Binary file not shown
BIN  packages/FSharp.Data.1.0.9/lib/net40/FSharp.Data.dll
View
Binary file not shown
BIN  packages/FSharp.Data.1.0.9/lib/net40/FSharp.Data.pdb
View
Binary file not shown
BIN  packages/FSharp.Data.Experimental.1.0.1/FSharp.Data.Experimental.1.0.1.nupkg
View
Binary file not shown
BIN  packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.Experimental.dll
View
Binary file not shown
BIN  packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.Experimental.pdb
View
Binary file not shown
BIN  packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.dll
View
Binary file not shown
BIN  packages/FSharp.Data.Experimental.1.0.1/lib/net40/FSharp.Data.pdb
View
Binary file not shown
Something went wrong with that request. Please try again.