For WASM, we need to provide the capability to do runtime checks, which means we should provide an OSPlatform
entry for it:
C#
namespace System.Runtime.InteropServices
{
public partial enum Architecture
{
Wasm
}
public partial struct OSPlatform
{
public static OSPlatform Browser { get; } = new OSPlatform(nameof(Browser));
}
}
@dotnet/fxdc @marek-safar @mhutch @lewing @SteveSandersonMS @danroth27
Seems like the wrong check. WASM inside and outside of the browser will have different capabilities
So what would you suggest we do? I can see two options:
WasmInBrowser
and WasmOutOfBrowser
WasmInBrowser
) and host specific platforms for out of browser (such as WasmNodeJs
, WasmElectronJs
)Thoughts?
Should the browser be the OS here, forgetting WASM? Then when we understand WASM out of the browser we add that?
Should the browser be the OS here, forgetting WASM?
Maybe, but this would mean that code that needs to #if for Blazor would have to detect all browsers, which seems fragile. We could, of course, expose a new API IsBrowser
and use that but I'm not sure I like that more.
Should the browser be the OS here
To me, the analogy is that WASM is the architecture and the browser is the OS.
```c#
public enum Architecture
{
X86 = 0,
X64 = 1,
Arm = 2,
Arm64 = 3,
public readonly partial struct OSPlatform
{
Blazor would have to detect all browsers
Why would Blazor have to detect all browsers? If that's for a specific feature we could add the to RuntimeFeatures (e.g. IsThreadingSupported
).
What we didn't solve though is how will one get the underlying OS for WASM. We had few requests for that info already, see https://github.com/mono/mono/issues/18627
Having a way to know youâre in a browser, as opposed to some other WebAssembly environment, makes sense. Marekâs scheme above sounds good to me.
Just want to clarify for anyone who might think we want to say which browser or host OS youâre in (eg differentiating Chrome vs Firefox, or Firefox on Windows vs Firefox on Android, or a specific browser version number), I think that should be an anti-goal. We should not try to do that because (1) itâs widely accepted to be a bad idea to infer feature support that way compared with actual feature detection, and (2) browsers are increasingly locking down such info on privacy grounds. Even if we had a way to do some of that today, we should expect that browsers may stop providing such info in the future. Itâs better just to say âsome browserâ.
This needs more thought.
I like Marek's take. I like Architecture = Wasm.
From webassembly.org:
WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine.
There are at least three mainline scenarios:
wasm and wasmtime seem like they are of the same kind (different environments). Wasi is more like a TFM, IMO.
Marek's suggestion sounds great to me too, i.e. architecture=Wasm, OS=WebBrowser.
(As a minor tweak, I'd suggest renaming WebBrowser to Browser, but it's not a big deal either way.)
Is there anything else to discuss, or is this the plan of record?
Marek's suggestion sounds good to me as well (and I also have a slight preference for "Browser" over "WebBrowser" but either is fine).
I like Marek's take. I like Architecture = Wasm.
From webassembly.org:
WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine.
There are at least three mainline scenarios:
wasm and wasmtime seem like they are of the same kind (different environments). Wasi is more like a TFM, IMO.
I just want to note that from the implementation side the big difference in those cases the existence of a paired javascript runtime that allows you to do things that are not currently possible in wasm only. There are other important differences in what features that runtime supports (browser vs v8 etc.) but they are smaller.
@terrajobst who can review this as you are the only assignee?
@marek-safar
It's going through the API review process, which is @dotnet/fxdc.
@terrajobst What's the timeline on that review process? Our code-complete date for the RC is tomorrow. Do you think this review can be done today, or who is it that needs to be pinged on that? We reached consensus already so hopefully this is just a formality.
Happening right now đ
Wasm
to WebAssembly
, but the RIDs will use wasm
, so it makes more sense to aling the names.OSPlatform.IsOSPlatform(OSPlatform.Windows)
return true
when running inside a browser on Windows. We concluded no, because that would likely break more people. Parties who care, need to use a more specific API that returns, for example, the user agent string.browser-wasm
, akin to win-x86
.C#
namespace System.Runtime.InteropServices
{
public partial enum Architecture
{
Wasm
}
public partial struct OSPlatform
{
public static OSPlatform Browser { get; } = new OSPlatform(nameof(Browser));
}
}
what are the plans for the RIDs?
@terrajobst waiting for approval at #34940
That OS/Platform design looks like it's in dire need of an overhaul (or perhaps deprecation; I think a better abstraction altogether might be in order). I also wonder where Windows 10 ARM fits in that picture. I know there's a RID for it and, similarly, the .NET 5 specs for TFMs/RIDs are indicating that WASM/Blazor will be a RID ("browser" - which I think is an appropriate solution, especially since there are non-browser WASM implementations which could be great mechanisms for portability in the future), but I would think that the runtime OS/Platform would generally align with the compile-time target publish profiles (i.e. Platform, Runtime, Architecture, etc.).
I understand this issue is particularly about Mono's implementation for the WASM runtime, but I wonder if a newer API might be in order that is more future-flexible/open/aligned with a growing list of runtimes and community support; presumably additional room for platform metadata (with less Windows-specific terminology) might be helpful as well (per the discussion around WASM-in-Electron vs in-browser, etc.). It might actually be helpful to identify which browser/version (though I would say browser User-Agent sniffing is generally frowned upon for feature checking now) as well as the OS that the browser/electron app is running on (could be very helpful to know that Blazor is running on iOS or on Windows), which *nix distro, which processor architecture (32 vs 64 pointer sizes no longer identify this, even on Windows) a .NET Standard library is running in without having to make 30 RID-specific compiled outputs just to hardcode a platform into its compiled output, for instance. In Blazor's case it would be possible to use JS-interop to determine this as well as the runtime might be able to, but I think there's still reason to consider being more thoughtful about a single reasonably accurate source of the truth (reasonably accurate because things like this can always be fudged, much as Reflection or debugger APIs could be used to get at things one generally shouldn't expect). At least runtimes should have the opportunity to identify as much as they can, even if much of the information is considered optional or best-guess.
One design consideration that particularly comes to mind looking at all this is that I feel like requiring closed BCL enumeration values for these types of things makes an unnecessary barrier to entry for new runtimes/platforms/architectures. For backwards compatibility sake we probably still need to populate these with some sort of meaningful values for the time being, but from this issue and the discussions I've seen in other repos related to it, this solution seems inaccurate (i.e. "Browser" is not an OS) and smells of a recurring problem if a better design isn't sought. This feels a little hacky to me, like a short-term narrow-sighted solution to a larger long-term problem.
The managed side of this change landed in https://github.com/dotnet/runtime/pull/34781 and the native side in https://github.com/dotnet/runtime/pull/36665 so this is done now.
I understand Microsoft is not providing any specific api for web assembly, but if you provide net5.0-wasm, we can create a nuget package which uses another nuget package, only for its wasm target or for non wasm targets based on requirements.
For example, at the moment, Xamarin Essentials has no support for wasm, but does support windows/android/iOS, so in my nuget package, I can use Xamarin Essentials for android/iOS/windows builds of my nuget package, and someone who uses my nuget package in his blazor app, is not forced to push xamarin essentials dll to client side browser!
Imaging I'm creating a nuget package called EasyLocalStorage which wraps Xamarin Essentials' Preferences and Blazored/LocalStorage.
I could do followings in my nuget package's csproj file:
<PackageReference Include="Xamarin.Essentials" Version="1.5.3.2" Condition=" '$(TargetFramework)' == 'net5.0-android' OR '$(TargetFramework)' == 'net5.0-iOS' OR '$(TargetFramework)' == 'net5.0-Windows'" />
<PackageReference Include="Blazored.LocalStorage" Version="2.1.5.0" Condition=" '$(TargetFramework)' == 'net5.0-wasm' />
Then I publish "EasyLocalStorage" nuget package which works across web/android/iOS/Windows and in android version of the apps which is using this nuget package, you won't see Blazored.LocalStorage! and in blazor app which is using this nuget package, you won't see Xamarin.Essentials!
Most helpful comment
To me, the analogy is that WASM is the architecture and the browser is the OS.
```c#
public enum Architecture
{
X86 = 0,
X64 = 1,
Arm = 2,
Arm64 = 3,
}
}
```
Why would Blazor have to detect all browsers? If that's for a specific feature we could add the to RuntimeFeatures (e.g.
IsThreadingSupported
).What we didn't solve though is how will one get the underlying OS for WASM. We had few requests for that info already, see https://github.com/mono/mono/issues/18627