SpawnDev.BlazorJS
1.6.3
See the version list below for details.
dotnet add package SpawnDev.BlazorJS --version 1.6.3
NuGet\Install-Package SpawnDev.BlazorJS -Version 1.6.3
<PackageReference Include="SpawnDev.BlazorJS" Version="1.6.3" />
paket add SpawnDev.BlazorJS --version 1.6.3
#r "nuget: SpawnDev.BlazorJS, 1.6.3"
// Install SpawnDev.BlazorJS as a Cake Addin #addin nuget:?package=SpawnDev.BlazorJS&version=1.6.3 // Install SpawnDev.BlazorJS as a Cake Tool #tool nuget:?package=SpawnDev.BlazorJS&version=1.6.3
NuGet
Package | Description | Link |
---|---|---|
SpawnDev.BlazorJS | Enhanced Blazor WebAssembly Javascript interop | |
SpawnDev.BlazorJS.WebWorkers | Blazor WebAssembly WebWorkers and SharedWebWorkers |
SpawnDev.BlazorJS
An easy Javascript interop library designed specifically for client side Blazor.
Supports Blazor WebAssembly .Net 6 and .Net 7.
- Use Javascript libraries in Blazor without writing any Javascript code.
- Alternative access to IJSRuntime JS is globally available without injection and is usable on the first line of Program.cs
- Get and set global properties via JS.Set and JS.Get
- Create new Javascript objects with JS.New
- Get and set object properties via IJSInProcessObjectReference extended methods
- Create Callbacks that can be sent to Javascript event listeners or assigned to javascript variables
JS
// Get Set
var innerHeight = JS.Get<int>("window.innerHeight");
JS.Set("document.title", "Hello World!");
// Call
var item = JS.Call<string?>("localStorage.getItem", "itemName");
JS.CallVoid("addEventListener", "resize", Callback.Create(() => Console.WriteLine("WindowResized"), _callBacks));
IJSInProcessObjectReference extended
// Get Set
var window = JS.Get<IJSInProcessObjectReference>("window");
window.Set("myVar", 5);
var myVar = window.Get<int>("myVar");
// Call
window.CallVoid("addEventListener", "resize", Callback.Create(() => Console.WriteLine("WindowResized")));
Create a new Javascript object
var worker = JS.New("Worker", myWorkerScript);
Pass callbacks to Javascript
JS.Set("testCallback", Callback.Create<string>((strArg) => {
Console.WriteLine($"Javascript sent: {strArg}");
// this prints "Hello callback!"
}));
// in Javascript
testCallback('Hello callback!');
JSObject
JSObjects are wrappers around IJSInProcessReference objects that can be passed to and from Javascript and allow strongly typed access to the underlying object.
Use the extended functions of IJSInProcessObjectReference to work with Javascript objects or use the growing library of over 100 of the most common Javascript objects, including ones for Window, HTMLDocument, WebStorage (localStorage and sessionStorage), WebGL, WebRTC, and more in SpawnDev.BlazorJS.JSObjects. JSObjects are wrappers around IJSInProcessObjectReference that allow strongly typed use.
Custom JSObjects
Implement your own JSObject classes for Javascript objects not already available in the BlazorJS.JSObjects library.
Instead of this (simple but not as reusable)
var audio = JS.New("Audio", "https://some_audio_online");
audio.CallVoid("play");
You can do this...
Create a custom JSObject wrapper
[JsonConverter(typeof(JSObjectConverter<Audio>))]
public class Audio : JSObject
{
public Audio(IJSInProcessObjectReference _ref) : base(_ref) { }
public Audio(string url) : base(JS.New("Audio", url)) { }
public void Play() => JSRef.CallVoid("play");
}
Then use your new object
var audio = new Audio("https://some_audio_online");
audio.Play();
SpawnDev.BlazorJS.WebWorkers
- Easily call Blazor Services in separate threads with WebWorkers and SharedWebWorkers
Firefox WebWorkers note:
Firefox does not support dynamic modules in workers, which originally made BlazorJS.WebWorkers fail in that browser.
I wrote code that changes the scripts on the fly before they are loaded to workaround this limitation until Firefox finishes worker module integration. It is possible some other browsers may have this issue. Issues can be reported here on GitHub.
https://bugzilla.mozilla.org/show_bug.cgi?id=1540913#c6
https://bugzilla.mozilla.org/show_bug.cgi?id=1247687
Example WebWorkerService setup and usage
// Program.cs
...
using SpawnDev.BlazorJS;
using SpawnDev.BlazorJS.WebWorkers;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
if (JS.IsWindow)
{
// we can skip adding dom objects in non UI threads
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
}
// add services
builder.Services.AddSingleton((sp) => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
// SpawnDev.BlazorJS.WebWorkers
builder.Services.AddSingleton<WebWorkerService>();
// app specific services...
builder.Services.AddSingleton<MathsService>();
// build
WebAssemblyHost host = builder.Build();
// init WebWorkerService
var workerService = host.Services.GetRequiredService<WebWorkerService>();
await workerService.InitAsync();
await host.RunAsync();
WebWorker
// Create a WebWorker
var webWorker = await workerService.GetWebWorker();
// Call a registered service on the worker thread with your arguments
// Action types can be passed for progress reporting
var result = await webWorker.InvokeAsync<MathsService, string>("CalculatePiWithActionProgress", piDecimalPlaces, new Action<int>((i) =>
{
piProgress = i;
StateHasChanged();
}));
SharedWebWorker
Calling GetSharedWebWorker in another window with the same sharedWorkerName will return the same SharedWebWorker
// Create or get SHaredWebWorker with the provided sharedWorkerName
var sharedWebWorker = await workerService.GetSharedWebWorker("workername");
// Just like WebWorker but shared
// Call a registered service on the worker thread with your arguments
var result = await sharedWebWorker.InvokeAsync<MathsService, string>("CalculatePiWithActionProgress", piDecimalPlaces, new Action<int>((i) =>
{
piProgress = i;
StateHasChanged();
}));
Send events
// Optionally listen for event messages
worker.OnMessage += (sender, msg) =>
{
if (msg.TargetName == "progress")
{
PiProgress msgData = msg.GetData<PiProgress>();
piProgress = msgData.Progress;
StateHasChanged();
}
};
// From SharedWebWorker or WebWorker threads send an event to connected parents
workerService.SendEventToParents("progress", new PiProgress { Progress = piProgress });
// Or on send an event to a connected worker
webWorker.SendEvent("progress", new PiProgress { Progress = piProgress });
Worker Transferable JSObjects
When working with workers in Javascript you can optionally tell Javascript (via the MessagePort.postMessage method) to transfer some of the objects instead of copying them.
WebWorkerService, when calling services on a worker, will transfer any transferable types by default. To disable the transferring of a return value, parameter, or property use the WorkerTransferAttribute.
Example
public class ProcessFrameResult : IDisposable
{
[WorkerTransfer(false)]
public ArrayBuffer? ArrayBuffer { get; set; }
public byte[]? HomographyBytes { get; set; }
public void Dispose(){
ArrayBuffer?.Dispose();
}
}
[return: WorkerTransfer(false)]
public async Task<ProcessFrameResult?> ProcessFrame([WorkerTransfer(false)] ArrayBuffer? frameBuffer, int width, int height, int _canny0, int _canny1, double _needlePatternSize)
{
var ret = new ProcessFrameResult();
// ...
return ret;
}
In the above example; the WorkerTransferAttribute on the return type set to false will prevent all properties of the return type from being transferred.
Transferable JSObject types
ArrayBuffer
MessagePort
ReadableStream
WritableStream
TransformStream
AudioData
ImageBitmap
VideoFrame
OffscreenCanvas
RTCDataChannel
NOTE: The above code shows quick examples. Some objects implement IDisposable, such as all JSObject, IJSInProcessObjectReference, and Callback, and need to be disposed when no longer used. Disposable objects returned from a Blazor service in a WebWorker or SharedWorker are automatically disposed after the data has been sent to the calling thread.
Support
Inspired by Tewr's BlazorWorker implementation. Thank you! I wrote my implementation from scratch as I needed workers in .Net 7.
https://github.com/Tewr/BlazorWorker
BlazorJS and WebWorkers Demo
https://blazorjs.spawndev.com/
Buy me a coffee
Product | Versions 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 is compatible. 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. |
-
net6.0
- Microsoft.AspNetCore.Components.WebAssembly (>= 6.0.13)
- Microsoft.AspNetCore.Components.WebAssembly.DevServer (>= 6.0.13)
-
net7.0
NuGet packages (10)
Showing the top 5 NuGet packages that depend on SpawnDev.BlazorJS:
Package | Downloads |
---|---|
SpawnDev.BlazorJS.WebWorkers
Call Services and static methods in separate threads with WebWorkers and SharedWebWorkers. Run Blazor WASM in the ServiceWorker. |
|
SpawnDev.BlazorJS.WebTorrents
WebTorrents in Blazor WebAssembly |
|
SpawnDev.BlazorJS.VisNetwork
VisNetwork in Blazor WebAssembly |
|
SpawnDev.BlazorJS.FFmpegWasm
SpawnDev.BlazorJS.FFmpegWasm is a Blazor WASM wrapper around ffmpeg.wasm and contains only the base ffmpeg.js and 814.ffmpeg.js files. |
|
SpawnDev.BlazorJS.SimplePeer
SimplePeer WebRTC video, voice, and data channels for Blazor WebAssembly |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
2.5.22 | 130 | 11/25/2024 |
2.5.21 | 105 | 11/21/2024 |
2.5.20 | 101 | 11/20/2024 |
2.5.19 | 109 | 11/18/2024 |
2.5.18 | 85 | 11/17/2024 |
2.5.17 | 94 | 11/16/2024 |
2.5.16 | 89 | 11/15/2024 |
2.5.15 | 85 | 11/15/2024 |
2.5.14 | 97 | 11/14/2024 |
2.5.13 | 104 | 11/13/2024 |
2.5.12 | 104 | 11/10/2024 |
2.5.11 | 337 | 10/31/2024 |
2.5.10 | 1,313 | 10/9/2024 |
2.5.9 | 188 | 9/27/2024 |
2.5.8 | 3,226 | 8/13/2024 |
2.5.7 | 99 | 8/13/2024 |
2.5.6 | 84 | 8/8/2024 |
2.5.5 | 265 | 8/7/2024 |
2.5.4 | 130 | 8/6/2024 |
2.5.3 | 94 | 8/5/2024 |
2.5.2 | 97 | 8/5/2024 |
2.5.1 | 237 | 7/26/2024 |
2.5.0 | 113 | 7/26/2024 |
2.4.7 | 119 | 7/24/2024 |
2.4.6 | 221 | 7/22/2024 |
2.4.5 | 186 | 7/19/2024 |
2.4.4 | 146 | 7/18/2024 |
2.4.3 | 259 | 7/16/2024 |
2.4.2 | 102 | 7/15/2024 |
2.4.0 | 99 | 7/15/2024 |
2.3.8 | 106 | 7/14/2024 |
2.3.7 | 1,112 | 7/9/2024 |
2.3.6 | 127 | 7/8/2024 |
2.3.5 | 140 | 7/6/2024 |
2.3.4 | 297 | 7/4/2024 |
2.3.3 | 389 | 6/23/2024 |
2.3.2 | 322 | 6/16/2024 |
2.3.1 | 248 | 6/13/2024 |
2.3.0 | 183 | 6/12/2024 |
2.2.106 | 253 | 6/5/2024 |
2.2.105 | 289 | 5/31/2024 |
2.2.104 | 177 | 5/30/2024 |
2.2.103 | 163 | 5/29/2024 |
2.2.102 | 173 | 5/28/2024 |
2.2.101 | 141 | 5/22/2024 |
2.2.100 | 167 | 5/17/2024 |
2.2.99 | 128 | 5/17/2024 |
2.2.98 | 134 | 5/16/2024 |
2.2.97 | 141 | 5/15/2024 |
2.2.96 | 102 | 5/14/2024 |
2.2.95 | 125 | 5/13/2024 |
2.2.94 | 565 | 5/11/2024 |
2.2.93 | 134 | 5/7/2024 |
2.2.92 | 130 | 5/7/2024 |
2.2.91 | 153 | 5/3/2024 |
2.2.90 | 96 | 5/3/2024 |
2.2.89 | 83 | 5/2/2024 |
2.2.88 | 95 | 5/2/2024 |
2.2.87 | 315 | 4/26/2024 |
2.2.86 | 140 | 4/26/2024 |
2.2.85 | 426 | 4/18/2024 |
2.2.84 | 125 | 4/18/2024 |
2.2.83 | 160 | 4/16/2024 |
2.2.82 | 488 | 4/8/2024 |
2.2.81 | 138 | 4/8/2024 |
2.2.80 | 147 | 4/7/2024 |
2.2.79 | 141 | 4/6/2024 |
2.2.78 | 141 | 4/5/2024 |
2.2.77 | 152 | 4/5/2024 |
2.2.76 | 149 | 4/4/2024 |
2.2.75 | 132 | 4/4/2024 |
2.2.73 | 131 | 4/3/2024 |
2.2.72 | 135 | 4/3/2024 |
2.2.71 | 156 | 4/3/2024 |
2.2.70 | 133 | 4/2/2024 |
2.2.69 | 326 | 4/1/2024 |
2.2.68 | 163 | 3/29/2024 |
2.2.67 | 296 | 3/27/2024 |
2.2.66 | 188 | 3/24/2024 |
2.2.65 | 155 | 3/21/2024 |
2.2.64 | 215 | 3/11/2024 |
2.2.63 | 181 | 3/9/2024 |
2.2.62 | 146 | 3/7/2024 |
2.2.61 | 152 | 3/6/2024 |
2.2.60 | 144 | 3/6/2024 |
2.2.58 | 193 | 3/2/2024 |
2.2.57 | 671 | 2/24/2024 |
2.2.56 | 177 | 2/18/2024 |
2.2.55 | 134 | 2/17/2024 |
2.2.53 | 140 | 2/15/2024 |
2.2.52 | 152 | 2/15/2024 |
2.2.51 | 136 | 2/15/2024 |
2.2.50 | 126 | 2/13/2024 |
2.2.49 | 942 | 2/2/2024 |
2.2.48 | 1,401 | 12/29/2023 |
2.2.47 | 193 | 12/20/2023 |
2.2.46 | 202 | 12/15/2023 |
2.2.45 | 163 | 12/10/2023 |
2.2.44 | 144 | 12/10/2023 |
2.2.42 | 157 | 12/9/2023 |
2.2.41 | 160 | 12/9/2023 |
2.2.40 | 138 | 12/8/2023 |
2.2.38 | 1,192 | 11/21/2023 |
2.2.37 | 477 | 11/16/2023 |
2.2.36 | 133 | 11/16/2023 |
2.2.35 | 169 | 11/14/2023 |
2.2.34 | 121 | 11/13/2023 |
2.2.33 | 89 | 11/10/2023 |
2.2.32 | 109 | 11/10/2023 |
2.2.31 | 87 | 11/9/2023 |
2.2.28 | 103 | 11/7/2023 |
2.2.27 | 161 | 10/31/2023 |
2.2.26 | 216 | 10/22/2023 |
2.2.25 | 110 | 10/20/2023 |
2.2.24 | 97 | 10/20/2023 |
2.2.23 | 102 | 10/20/2023 |
2.2.22 | 95 | 10/20/2023 |
2.2.21 | 105 | 10/20/2023 |
2.2.20 | 101 | 10/19/2023 |
2.2.19 | 91 | 10/19/2023 |
2.2.18 | 92 | 10/19/2023 |
2.2.17 | 199 | 10/13/2023 |
2.2.16 | 488 | 10/12/2023 |
2.2.15 | 95 | 10/12/2023 |
2.2.14 | 138 | 10/5/2023 |
2.2.13 | 116 | 10/5/2023 |
2.2.12 | 93 | 10/5/2023 |
2.2.11 | 257 | 10/3/2023 |
2.2.10 | 224 | 9/18/2023 |
2.2.9 | 91 | 9/18/2023 |
2.2.8 | 283 | 9/14/2023 |
2.2.7 | 119 | 9/13/2023 |
2.2.6 | 6,711 | 9/6/2023 |
2.2.5 | 136 | 8/30/2023 |
2.2.4 | 170 | 8/26/2023 |
2.2.3 | 129 | 8/20/2023 |
2.2.2 | 116 | 8/18/2023 |
2.2.1 | 124 | 8/11/2023 |
2.2.0 | 210 | 7/17/2023 |
2.1.15 | 131 | 5/26/2023 |
2.1.14 | 111 | 5/20/2023 |
2.1.13 | 129 | 4/26/2023 |
2.1.12 | 191 | 4/21/2023 |
2.1.11 | 117 | 4/19/2023 |
2.1.10 | 124 | 4/19/2023 |
2.1.8 | 158 | 4/10/2023 |
2.1.7 | 178 | 3/27/2023 |
2.1.6 | 170 | 3/24/2023 |
2.1.5 | 142 | 3/23/2023 |
2.1.4 | 139 | 3/23/2023 |
2.1.3 | 141 | 3/23/2023 |
2.1.2 | 146 | 3/21/2023 |
2.1.0 | 144 | 3/21/2023 |
2.0.3 | 144 | 3/21/2023 |
2.0.2 | 141 | 3/20/2023 |
2.0.1 | 148 | 3/20/2023 |
2.0.0 | 147 | 3/20/2023 |
1.9.2 | 153 | 3/14/2023 |
1.8.1 | 141 | 3/11/2023 |
1.8.0 | 139 | 3/10/2023 |
1.7.1 | 143 | 3/10/2023 |
1.7.0 | 142 | 3/8/2023 |
1.6.4 | 156 | 3/1/2023 |
1.6.3 | 365 | 1/31/2023 |
1.6.2 | 378 | 1/24/2023 |
1.6.1 | 401 | 1/11/2023 |
1.6.0 | 396 | 1/11/2023 |
1.5.0 | 458 | 12/23/2022 |
1.4.0 | 411 | 12/20/2022 |
1.3.0 | 413 | 12/16/2022 |
1.2.7 | 357 | 12/16/2022 |
1.2.5 | 371 | 12/14/2022 |
1.2.4.1 | 354 | 12/13/2022 |
1.2.4 | 355 | 12/13/2022 |
1.2.3 | 353 | 12/13/2022 |
1.2.1 | 342 | 12/10/2022 |
1.2.0 | 344 | 12/10/2022 |
1.1.0 | 336 | 12/6/2022 |
1.0.0 | 340 | 12/6/2022 |