public static async ValueTask <RemoteJSDataStream> CreateRemoteJSDataStreamAsync(
            RemoteJSRuntime runtime,
            IJSStreamReference jsStreamReference,
            long totalLength,
            long signalRMaximumIncomingBytes,
            TimeSpan jsInteropDefaultCallTimeout,
            CancellationToken cancellationToken = default)
        {
            // Enforce minimum 1 kb, maximum 50 kb, SignalR message size.
            // We budget 512 bytes overhead for the transfer, thus leaving at least 512 bytes for data
            // transfer per chunk with a 1 kb message size.
            // Additionally, to maintain interactivity, we put an upper limit of 50 kb on the message size.
            var chunkSize = signalRMaximumIncomingBytes > 1024 ?
                            Math.Min(signalRMaximumIncomingBytes, 50 * 1024) - 512 :
                            throw new ArgumentException($"SignalR MaximumIncomingBytes must be at least 1 kb.");

            var streamId           = runtime.RemoteJSDataStreamNextInstanceId++;
            var remoteJSDataStream = new RemoteJSDataStream(runtime, streamId, totalLength, jsInteropDefaultCallTimeout, cancellationToken);
            await runtime.InvokeVoidAsync("Blazor._internal.sendJSDataStream", jsStreamReference, streamId, chunkSize);

            return(remoteJSDataStream);
        }
        // ReceiveJSDataChunk is used in a fire-and-forget context, so it's responsible for its own
        // error handling.
        internal async Task <bool> ReceiveJSDataChunk(long streamId, long chunkId, byte[] chunk, string error)
        {
            AssertInitialized();
            AssertNotDisposed();

            try
            {
                return(await Renderer.Dispatcher.InvokeAsync(() =>
                {
                    return RemoteJSDataStream.ReceiveData(JSRuntime, streamId, chunkId, chunk, error);
                }));
            }
            catch (Exception ex)
            {
                // An error completing JS interop means that the user sent invalid data, a well-behaved
                // client won't do this.
                Log.ReceiveJSDataChunkException(_logger, streamId, ex);
                await TryNotifyClientErrorAsync(Client, GetClientErrorMessage(ex, "Invalid chunk supplied to stream."));

                UnhandledException?.Invoke(this, new UnhandledExceptionEventArgs(ex, isTerminating: false));
                return(false);
            }
        }