Skip to content

Commit 9a03622

Browse files
committed
Added test for module mode in the demo app
1 parent 132e07c commit 9a03622

10 files changed

Lines changed: 193 additions & 7 deletions

SpawnDev.BlazorJS.WebWorkers.Demo/Layout/NavMenu.razor

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather
2525
</NavLink>
2626
</div>
27+
<div class="nav-item px-3">
28+
<NavLink class="nav-link" href="TestModuleWorker">
29+
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> TestModuleWorker
30+
</NavLink>
31+
</div>
2732
</nav>
2833
</div>
2934

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
@page "/TestModuleWorker"
2+
@using SpawnDev.BlazorJS.JSObjects
3+
@implements IDisposable
4+
5+
<PageTitle>Module Worker Test</PageTitle>
6+
7+
<h1>Module Worker Test</h1>
8+
<p>
9+
This component tests starting a web worker in module mode.<br />
10+
Some Javascript libraries require module mode, but service workers must be either 'classic' mode and use importScripts or 'module' mode and use static imports.<br />
11+
Window, SharedWebWorker, and DedicatedWebWorker can use dynamic imports but that is not supported in a ServiceWorker.<br />
12+
SpawnDev.BlazorJS.WebWorkers needs to support starting in a ServiceWorker that is running in 'module' mode to enable support for ESM Javascript modules.<br />
13+
Running in a Worker that is started in module mode is very similar to running in a ServiceWorker that is started in module mode, but is easier to test.
14+
</p>
15+
16+
<button class="btn btn-primary" @onclick="IncrementCount">Run</button>
17+
18+
@code {
19+
[Inject]
20+
WebWorkerService WebWorkerService { get; set; } = default!;
21+
22+
public void Dispose()
23+
{
24+
25+
}
26+
private async Task IncrementCount()
27+
{
28+
var worker = await WebWorkerService.GetWebWorker(new WebWorkerOptions
29+
{
30+
// ScriptUrl = new Uri(new Uri(WebWorkerService.AppBaseUri), "app.worker.module.js").ToString(),
31+
// QueryParams = new Dictionary<string, string>
32+
// {
33+
// { "autoStart", "0" },
34+
// { "verbose", "1" },
35+
// },
36+
WorkerOptions = new WorkerOptions
37+
{
38+
Type = "module"
39+
}
40+
});
41+
var ret = await worker!.Run(() => TestMethod(null!));
42+
Console.WriteLine($"Worker returned: {ret}");
43+
}
44+
static int TestMethod([FromServices] BlazorJSRuntime JS)
45+
{
46+
JS.Log($"TestMethod: {JS.GlobalScope}");
47+
return 42;
48+
}
49+
}

SpawnDev.BlazorJS.WebWorkers.Demo/Program.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,36 @@
11
using Microsoft.AspNetCore.Components.Web;
22
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
33
using SpawnDev.BlazorJS;
4+
using SpawnDev.BlazorJS.JSObjects;
45
using SpawnDev.BlazorJS.WebWorkers;
56
using SpawnDev.BlazorJS.WebWorkers.Demo;
7+
using SpawnDev.BlazorJS.WebWorkers.Demo.Services;
68

7-
var builder = WebAssemblyHostBuilder.CreateDefault(args);
8-
builder.RootComponents.Add<App>("#app");
9-
builder.RootComponents.Add<HeadOutlet>("head::after");
109

10+
var builder = WebAssemblyHostBuilder.CreateDefault(args);
1111
builder.Services.AddBlazorJSRuntime(out var JS);
12+
Console.WriteLine($">>> BlazorJS Running: {JS.GlobalScope.ToString()}");
13+
1214
builder.Services.AddWebWorkerService();
1315

16+
builder.Services.RegisterServiceWorker<AppServiceWorker>(new ServiceWorkerConfig
17+
{
18+
ScriptURL = "./app.service-worker.module.js",
19+
Options = new ServiceWorkerRegistrationOptions
20+
{
21+
Scope = "./",
22+
Type = "module",
23+
},
24+
});
25+
1426
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
1527

28+
if (JS.IsWindow)
29+
{
30+
builder.RootComponents.Add<App>("#app");
31+
builder.RootComponents.Add<HeadOutlet>("head::after");
32+
}
33+
1634
var host = await builder.Build().StartBackgroundServices();
1735

1836

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using SpawnDev.BlazorJS;
2+
using SpawnDev.BlazorJS.JSObjects;
3+
using SpawnDev.BlazorJS.WebWorkers;
4+
using System.Collections.Specialized;
5+
using System.Web;
6+
7+
namespace SpawnDev.BlazorJS.WebWorkers.Demo.Services
8+
{
9+
public class AppServiceWorker : ServiceWorkerEventHandler
10+
{
11+
public AppServiceWorker(BlazorJSRuntime js) : base(js)
12+
{
13+
14+
}
15+
// called before any ServiceWorker events are handled
16+
protected override async Task OnInitializedAsync()
17+
{
18+
// This service may start in any scope. This will be called before the app runs.
19+
// If JS.IsWindow == true be careful not stall here.
20+
// you can do initialization based on the scope that is running
21+
Log("GlobalThisTypeName", JS.GlobalThisTypeName);
22+
}
23+
24+
protected override async Task ServiceWorker_OnInstallAsync(ExtendableEvent e)
25+
{
26+
Log($"ServiceWorker_OnInstallAsync");
27+
_ = ServiceWorkerThis!.SkipWaiting(); // returned task can be ignored
28+
}
29+
30+
protected override async Task ServiceWorker_OnActivateAsync(ExtendableEvent e)
31+
{
32+
Log($"ServiceWorker_OnActivateAsync");
33+
await ServiceWorkerThis!.Clients.Claim();
34+
}
35+
36+
protected override async Task<Response> ServiceWorker_OnFetchAsync(FetchEvent e)
37+
{
38+
Log($"ServiceWorker_OnFetchAsync", e.Request.Method, e.Request.Url);
39+
Response ret;
40+
try
41+
{
42+
ret = await JS.Fetch(e.Request);
43+
}
44+
catch (Exception ex)
45+
{
46+
ret = new Response(ex.Message, new ResponseOptions { Status = 500, StatusText = ex.Message, Headers = new Dictionary<string, string> { { "Content-Type", "text/plain" } } });
47+
Log($"ServiceWorker_OnFetchAsync failed: {ex.Message}");
48+
}
49+
return ret;
50+
}
51+
52+
protected override async Task ServiceWorker_OnMessageAsync(ExtendableMessageEvent e)
53+
{
54+
Log($"ServiceWorker_OnMessageAsync");
55+
}
56+
57+
protected override async Task ServiceWorker_OnPushAsync(PushEvent e)
58+
{
59+
Log($"ServiceWorker_OnPushAsync");
60+
}
61+
62+
protected override async Task ServiceWorker_OnPushSubscriptionChangeAsync(PushSubscriptionChangeEvent e)
63+
{
64+
Log($"ServiceWorker_OnPushSubscriptionChangeAsync");
65+
}
66+
67+
protected override async Task ServiceWorker_OnSyncAsync(SyncEvent e)
68+
{
69+
Log($"ServiceWorker_OnSyncAsync");
70+
}
71+
72+
protected override async Task ServiceWorker_OnNotificationCloseAsync(NotificationEvent e)
73+
{
74+
Log($"ServiceWorker_OnNotificationCloseAsync");
75+
}
76+
77+
protected override async Task ServiceWorker_OnNotificationClickAsync(NotificationEvent e)
78+
{
79+
Log($"ServiceWorker_OnNotificationClickAsync");
80+
}
81+
void Log(params object[] msg) => JS.Log(msg);
82+
}
83+
}

SpawnDev.BlazorJS.WebWorkers.Demo/SpawnDev.BlazorJS.WebWorkers.Demo.csproj

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313
</ItemGroup>
1414

1515
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
16-
<ProjectReference Include="..\SpawnDev.BlazorJS.WebWorkers\SpawnDev.BlazorJS.WebWorkers.csproj" />
16+
<!-- <ProjectReference Include="..\SpawnDev.BlazorJS.WebWorkers\SpawnDev.BlazorJS.WebWorkers.csproj" /> -->
17+
18+
<PackageReference Include="SpawnDev.BlazorJS.WebWorkers" Version="2.16.1-preview.28" />
1719
</ItemGroup>
1820

1921
<ItemGroup Condition=" '$(Configuration)' == 'Release' ">
20-
<PackageReference Include="SpawnDev.BlazorJS.WebWorkers" Version="2.9.0" />
22+
<PackageReference Include="SpawnDev.BlazorJS.WebWorkers" Version="2.16.1-preview.14" />
2123
</ItemGroup>
2224

2325
<!-- SpawnDev.BlazorJS.WebWorkers config -->
@@ -31,6 +33,6 @@
3133
- true - patch during build
3234
! NOTE - The asset manifest file (service-worker-assets.js) will be updated during publish build if using the ServiceWorkerAssetsManifest flag and WebWorkerPatchFramework == true
3335
-->
34-
<WebWorkerPatchFramework>false</WebWorkerPatchFramework>
36+
<WebWorkerPatchFramework>true</WebWorkerPatchFramework>
3537
</PropertyGroup>
3638
</Project>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// anything that needs to be set or run before other stuff must be in the first statically imported script because
2+
// static imports in the main file are loaded before any code, no matter the placement of the code or imports.
3+
4+
// this tells spawndev.blazorjs.webworkers.module.js not to start Blazor. We will start it with Blazor.start() and optionally with any startup changes we need.
5+
globalThis.autoStart = false;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// A custom service worker or web worker startup script can be used to static import Javascript libraries.
2+
// This was specifically tested to allow Blazor WASM to run in a Chrome Browser extension background ServiceWorker running in 'module' mode so it can run Transformers.js
3+
4+
import * as _globals from "./app.worker.module.globals.js"
5+
import * as _importShim from "./spawndev.blazorjs.webworkers.module.js"
6+
7+
// Start Blazor
8+
Blazor._startTask ??= Blazor.start();
9+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// anything that needs to be set or run before other stuff must be in the first statically imported script because
2+
// static imports in the main file are loaded before any code, no matter the placement of the code or imports.
3+
4+
// this tells spawndev.blazorjs.webworkers.module.js not to start Blazor. We will start it with Blazor.start() and optionally with any startup changes we need.
5+
globalThis.autoStart = false;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// A custom service worker or web worker startup script can be used to static import Javascript libraries.
2+
// This was specifically tested to allow Blazor WASM to run in a Chrome Browser extension background ServiceWorker running in 'module' mode so it can run Transformers.js
3+
4+
import * as _globals from "./app.worker.module.globals.js"
5+
import * as _importShim from "./spawndev.blazorjs.webworkers.module.js"
6+
7+
// Start Blazor
8+
Blazor._startTask ??= Blazor.start();
9+

SpawnDev.BlazorJS.WebWorkers.Demo/wwwroot/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
<a href="" class="reload">Reload</a>
3333
<a class="dismiss">🗙</a>
3434
</div>
35-
<script src="_framework/blazor.webassembly.js"></script>
35+
<!-- <script src="_framework/blazor.webassembly.js"></script> -->
36+
<script src="app.worker.module.js" type="module"></script>
3637
</body>
3738

3839
</html>

0 commit comments

Comments
 (0)