BlazorBindGen 0.0.3.7

dotnet add package BlazorBindGen --version 0.0.3.7                
NuGet\Install-Package BlazorBindGen -Version 0.0.3.7                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="BlazorBindGen" Version="0.0.3.7" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add BlazorBindGen --version 0.0.3.7                
#r "nuget: BlazorBindGen, 0.0.3.7"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install BlazorBindGen as a Cake Addin
#addin nuget:?package=BlazorBindGen&version=0.0.3.7

// Install BlazorBindGen as a Cake Tool
#tool nuget:?package=BlazorBindGen&version=0.0.3.7                

BlazorBindGen

NuGet Package NuGet Badge License: MIT

A binding generator for JS, Call any JS function or property in <b>Blazor Wasm and Server (Including MAUI hybrid)</b> without writing JS wrappers.

Why Use BlazorBindGen
  • very tiny Overhead ~13kb
  • No need to write JS wrappers
  • Support for Callbacks
  • Write JS code in C#
  • WASM and Server Supported
  • automatic memory management
Installation

Use Nuget Package Manager or .Net CLI

dotnet add package BlazorBindGen
Initialize BindGen
  1. on top of razor page add Import statements

@inject IJSRuntime runtime
@using BlazorBindGen
@using static BlazorBindGen.BindGen
@using JSCallBack=System.Action<BlazorBindGen.JObjPtr[]>; //optional Typedef 
  1. Intitialize the BindGen
    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        await InitAsync(runtime);
    }
    //on Server 
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
	if (!firstRender)
		return;
	await InitAsync(runtime);	
    }
Binding Samples

<b> → Js code is for explaination purpose only , you do not need to write js code anywhere.<br> → On Server use Async Version of functions (non async functions will throw PlatformNotSupportedException)</b>

Import JS libaries when ever you want in C#
// js equivalent
await import("https://unpkg.com/ml5@latest/dist/ml5.min.js");
//c# side
await ImportAsync("https://unpkg.com/ml5@latest/dist/ml5.min.js");

// js equivalent, importing modules 
let ml5=await import("https://unpkg.com/ml5@latest/dist/ml5.min.js");
//c# side
var ml5Ptr=await ImportRefAsync("https://unpkg.com/ml5@latest/dist/ml5.min.js");
Constructor Calls
//js side
var audio=new Audio(param);

//c# side code 
var_audio=Window.Construct("Audio",param); /* js reference to Audio Player */ 
Function Calls

//js equivalent 
alert("Hello");

//code to call alert in C#
Window.CallVoid("alert","hello");
Share JS object References
//js equivalent 
var video = document.querySelector("#videoElement");
//here document is property of window , and dcument has function querySelector


//c# code 
var video = Window["document"].CallRef("querySelector", "#videoElement");
//["documemnt"] will return reference to Property document of window , another way to write it is 
JObjPtr video = Window.PropRef("document").CallRef("querySelector", "#videoElement");
//CallRef function calls JS function and Returns a reference to it, instead of whole object 
Get Set Properties
// equivalent js code 
var ctx = c.getContext("2d");
var grd = ctx.createRadialGradient(75, 50, 5, 90, 60, 100);
ctx.fillStyle = grd;
		
//c# side 
var ctx=canvas.CallRef("getContext","2d");
var grad = ctx.CallRef("createLinearGradient", 0,0,400,0);
ctx.SetPropRef("fillStyle",grad); 
//assign a reference to grad(a JobjPtr reference) to property fillStyle of canvas context
Mapping JS property to C#
//js
var audio=new Audio();
audio.currentTime=6; //set
console.log(audio.currentTime); //get

//c# equivalent
JObjPtr _audio=Window.Construct("Audio"); /* js reference to Audio Player */ 
public double CurrentTime
{
    get => _audio.PropVal<double>("currentTime");
    set => _audio.SetPropVal("currentTime", value);
}
Map Js Callback to C# event
//js equivalent
var audio=new Audio();
audio.onloadeddata=()=>{ console.log("loaded"))};

//cs equivalent
{
   var _audio=Window.Construct("Audio"); /* js reference to Audio Player */ 
   _audio.SetPropCallBack("onloadedmetadata", (_) => OnLoadedMetaData?.Invoke(this));
}
public delegate void LoadedMetaDataHandler(object sender);
public event LoadedMetaDataHandler OnLoadedMetaData;

Be sure to check out sampleApp for more examples

Example (using ML5 in C# only)

@page "/ml5"

@using BlazorBindGen
@using static BlazorBindGen.BindGen
@using JSCallBack=System.Action<BlazorBindGen.JObjPtr[]>; //optional only needed to simplify callback type name

@inject IJSRuntime runtime

@if (isLoaded)
{
    <input type="text" class="bg-dark text-white border-light" @bind="predictText" placeholder="write review here " style="font-size:18px"/>
    <button class="btn btn-primary" id="mbtn" @onclick="Predict">Predict</button><br /><br />
    if(score>0)
    {
        <div class="alert alert-primary">
            <p>Review: @GetEmoji() <br />Score: @score</p>
        </div>
    }
}
else
{
    <div class="alert alert-warning">
        Fetching Movie Review Dataset (~16 MB)
    </div>
}
@code
{
    JWindow win;
    public JObjPtr sentiment;
    string predictText;
    bool isLoaded = false;
    double score;

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        await Init(runtime);
        win = Window;
        await ML5Init();
    }

    async Task ML5Init()
    {
        await Import("https://unpkg.com/ml5@latest/dist/ml5.min.js");
        Console.Clear();
        var ml5 = win["ml5"];
        sentiment = ml5.CallRef("sentiment", "movieReviews", (JSCallBack)OnModelLoaded);
    }

    void Predict()
    {
        var v = sentiment.Call<Score>("predict", predictText);
        score=v.score;
        StateHasChanged();
    }

    void OnModelLoaded(params JObjPtr[] args)
    {
        isLoaded = true;
        StateHasChanged();
    }

    string GetEmoji()
    {
        if (score > 0.7)
            return "😀";
        else if (score > 0.4)
            return "😐";
        else
            return "😥";

    }

    record Score(double score);

}


Experimentation Auto Bind Generator for WASM

Above example binding could also be generated with Source Generator for WASM .

using BlazorBindGen.Attributes;

namespace SampleApp.JSBinding
{
    [JSWindow] // represents JS Window class
    public static partial class DomWindow  
    {
        [JSProperty] 
        private static ML5 ml5; // refers to window.ml5 prop js side

    }
    [JSObject("https://unpkg.com/ml5@latest/dist/ml5.min.js")]
    public partial class ML5
    {
        [JSFunction("sentiment")]
        public partial Sentiment Sentiment(string modelName,OnModelLoadHandler onModelLoad);

        [JSCallback]
        public delegate void OnModelLoadHandler();

        [JSConstruct("p5")]
        public partial Sentiment Construct();
    }
    [JSObject]
    public partial class Sentiment
    {
        [JSFunction("predict")]
        public partial Score Predict(string text);
    }
    public record Score(double score);


}

see usage here

Warning
  1. BlazorBindGen Api is subject to change, API is not stable.
  2. Note: Blazor Server requires use of Async functions otherwise UI thread will be blocked by it or alternatively you can call BindGen functions on different thread <br/> #issue.
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.0.3.7 176 5/19/2024
0.0.3.6 112 3/29/2024
0.0.3.5 684 9/12/2022
0.0.3.4 580 9/12/2022
0.0.3.3 640 6/1/2022
0.0.3.2 756 1/24/2022
0.0.3.1 640 1/24/2022
0.0.3 629 1/24/2022
0.0.2 455 11/28/2021
0.0.1 189 7/21/2021