public static Task DispatchEvent(WebEventDescriptor eventDescriptor, string eventArgsJson)
        {
            //WebEventData webEventData = WebEventData.Parse(eventDescriptor,eventArgsJson);
            //return RendererRegistry.Find(eventDescriptor.BrowserRendererId).DispatchEventAsync(webEventData.EventHandlerId,webEventData.EventFieldInfo,webEventData.EventArgs);

            object    webEventData = _webEventDataParse.Invoke(null, new object[] { eventDescriptor, eventArgsJson });
            Renderer  renderer     = (Renderer)_rendererRegistryFind.Invoke(null, new object[] { eventDescriptor.BrowserRendererId });
            EventArgs eventArgs    = (EventArgs)_eventArgs.GetValue(webEventData);

            eventArgs = eventDescriptor.EventArgsType switch
            {
                "change" => new NativeChangeEventArgs((ChangeEventArgs)eventArgs, NativeJs.GetEventNative(eventArgsJson)),
                "clipboard" => new NativeClipboardEventArgs((ClipboardEventArgs)eventArgs, NativeJs.GetEventNative(eventArgsJson)),
                "drag" => new NativeDragEventArgs((DragEventArgs)eventArgs, NativeJs.GetEventNative(eventArgsJson)),
                "error" => new NativeErrorEventArgs((ErrorEventArgs)eventArgs, NativeJs.GetEventNative(eventArgsJson)),
                "focus" => new NativeFocusEventArgs((FocusEventArgs)eventArgs, NativeJs.GetEventNative(eventArgsJson)),
                "keyboard" => new NativeKeyboardEventArgs((KeyboardEventArgs)eventArgs, NativeJs.GetEventNative(eventArgsJson)),
                "mouse" => new NativeMouseEventArgs((MouseEventArgs)eventArgs, NativeJs.GetEventNative(eventArgsJson)),
                "pointer" => new NativePointerEventArgs((PointerEventArgs)eventArgs, NativeJs.GetEventNative(eventArgsJson)),
                "progress" => new NativeProgressEventArgs((ProgressEventArgs)eventArgs, NativeJs.GetEventNative(eventArgsJson)),
                "touch" => new NativeTouchEventArgs((TouchEventArgs)eventArgs, NativeJs.GetEventNative(eventArgsJson)),
                "unknown" => new NativeEventArgs((EventArgs)eventArgs, NativeJs.GetEventNative(eventArgsJson)),
                "wheel" => new NativeWheelEventArgs((WheelEventArgs)eventArgs, NativeJs.GetEventNative(eventArgsJson)),
                _ => eventArgs
            };
            return(renderer.DispatchEventAsync((ulong)_eventHandlerId.GetValue(webEventData), (EventFieldInfo)_eventFieldInfo.GetValue(webEventData), eventArgs));
        }
        public static Task DispatchFunction(NativeFuncDescriptor funcDescriptor, string funcArgsJson)
        {
            WeakReference funcReference = NativeJs.GetFunction(funcDescriptor.FuncId);

            object[] args = NativeJs.ParseJsonArgs(funcArgsJson).Cast <object[]>();
            return(InvokeAction(funcReference.Target, args));
        }
        internal object Eval()
        {
            StringBuilder  sb     = new StringBuilder();
            Utf8JsonWriter writer = new Utf8JsonWriter(new StringBuilderStream(sb));

            this.Visit(writer);
            writer.Flush();
            object result = NativeJs.ExecExpr(sb.ToString(), true);

            return(result);
        }
        public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
        {
            StringBuilder  sb     = new StringBuilder();
            Utf8JsonWriter writer = new Utf8JsonWriter(new StringBuilderStream(sb));

            writer.WriteStartObject();
            writer.WriteString("type", "setindex");
            writer.WritePropertyName("object");
            this.Visit(writer);
            WriteArray(writer, "indexes", indexes);
            writer.WritePropertyName("value");
            WriteValue(writer, value);
            writer.WriteEndObject();
            writer.Flush();
            NativeJs.ExecExpr(sb.ToString(), false);
            return(true);
        }
        protected void WriteValue(Utf8JsonWriter writer, object value)
        {
            value = NativeJs.ResolveJsObject(value);
            if (value == null)
            {
                writer.WriteNullValue();
            }
            else
            {
                switch (value)
                {
                case bool @bool:
                    writer.WriteBooleanValue(@bool);
                    break;

                case string str:
                    writer.WriteStringValue(str);
                    break;

                case DateTime dt:
                    writer.WriteStringValue(dt);
                    break;

                case byte @byte:
                    writer.WriteNumberValue(@byte);
                    break;

                case decimal dec:
                    writer.WriteNumberValue(dec);
                    break;

                case double dbl:
                    writer.WriteNumberValue(dbl);
                    break;

                case short int16:
                    writer.WriteNumberValue(int16);
                    break;

                case int int32:
                    writer.WriteNumberValue(int32);
                    break;

                case long int64:
                    writer.WriteNumberValue(int64);
                    break;

                case sbyte @sbyte:
                    writer.WriteNumberValue(@sbyte);
                    break;

                case float flt:
                    writer.WriteNumberValue(flt);
                    break;

                case ushort uint16:
                    writer.WriteNumberValue(uint16);
                    break;

                case uint uint32:
                    writer.WriteNumberValue(uint32);
                    break;

                case ulong uint64:
                    writer.WriteNumberValue(uint64);
                    break;

                case Expr expr:
                    expr.Visit(writer);
                    break;

                default:
                    throw new NotSupportedException($"{value.GetType()} is not supported on writing JS value");
                }
            }
        }