elringus / bootsharp

Compile C# solution into single-file ES module with auto-generated JavaScript bindings and type definitions
https://sharp.elringus.com
MIT License
673 stars 36 forks source link

Don't marshal `Task<[]>` of supported colletion items #138

Open elringus opened 10 months ago

elringus commented 10 months ago

.NET's JS interop currently is only able to marshal types with single-level nesting:

— hence we have to handle otherwise natively-supported arrays (eg, Task<byte[]>) in a special manner.

Workaround 1

Update: This workaround seems to no longer work in .NET 8.0.1, where it throws an error stating proxy for the associated method is not found.

Lift the array to object and marshal as JSType.Any:

[JSExport] [return: JSMarshalAs<JSType.Promise<JSType.Any>>]
private static async Task<object> GetArrayAsync ()
{
    await Task.Delay(1);
    return new[] { "foo", "bar", "baz" };
}

This is currently employed under the hood and doesn't require any action from end-user, but costs an extra allocation when unmarshalling from JS to C#.

Workaround 2

Wrap the call into two: first to wait for the async operation, second to get the array in a blocking manner, eg:

[JSFunction] Task OpenFile (string uri);
[JSFunction] byte[] GetOpenFileContent (string uri);

Task<byte[]> ReadFile (string uri)
{
    await OpenFile(uri);
    return GetOpenFileContent(uri);
}