public static JSValue AddClrObject(this JSObject target, IJSService value)
        {
            JSContext context = target.Context;
            var       jobj    = new JSObject(context);

            context.SetJSPropertyValue("__clr__obj", jobj);


            var methods = value
                          .GetType()
                          .GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
                          .ToList();

            var properties = value.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (var item in methods)
            {
                try
                {
                    JSClrFunction clrFunction = new JSClrFunction(context, (x) =>
                    {
                        // map parameters
                        return(item.Invoke(value,
                                           item
                                           .GetParameters()
                                           .Select((p, i) => (x[i] is JSValue jv) ? jv.ToType(p.ParameterType) : null).ToArray()));
                    });

                    jobj.InvokeProperty($"__{item.Name}", clrFunction);
                    var r = context.ExecuteScript($"__paramArrayToArrayParam(__clr__obj,__clr__obj.__{item.Name})", "AddClrObject", 0);
                    jobj.InvokeProperty(item.Name.ToCamelCase(), (Java.Lang.Object)r);
                }
        public AtomBridge()
        {
            try
            {
                Engine = new JSContext();
                Engine.SetExceptionHandler(new AppExceptionHandler((e) => {
                    if (e.Error != null)
                    {
                        System.Diagnostics.Debug.WriteLine($"{e.Error.Message()}\r\n{e.Error.Stack()}");
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine(e.ToString());
                    }
                }));

                // Client = (new AtomWebClient()).Client;
                Client = (new AppOkHttpClient()).Client;
                Engine.ExecuteScript("function __paramArrayToArrayParam(t, f) { return function() { var a = []; for(var i=0;i<arguments.length;i++) { a.push(arguments[i]); } return f.call(t, a); } }", "vm");
                // engine.SetJSPropertyValue("global", engine);
                Engine.SetJSPropertyValue("document", null);
                Engine.SetJSPropertyValue("location", null);

                // engine.Global.Put("global", engine.Global, false);
                // engine.Global.Put("App", Jint.Native.JsValue.FromObject(engine, WAContext.Current), true);
                // engine.Global.Put("bridge", Jint.Native.JsValue.FromObject(engine, this), true);

                // engine.Global.Put("document", Jint.Native.JsValue.Null, true);
                // Execute("var global = {};");
                var v8Bridge = Engine.AddClrObject(this);
                Engine.SetJSPropertyValue("bridge", v8Bridge);
                Execute("var console = {};");
                Execute("console.log = function(l) { bridge.log('log', l); };");
                Execute("console.warn = function(l) { bridge.log('warn', l); };");
                Execute("console.error = function(l) { bridge.log('error', l); if(l.stack) { bridge.log('error', l.stack); } };");

                Execute("console.log('Started .... ');");

                Execute("var setInterval = function(v,i){ return bridge.setInterval(v,i, false); };");
                Execute("var clearInterval = function(i){ bridge.clearInterval(i); };");
                Execute("var setTimeout = function(v,i){ return bridge.setInterval(v,i, true); };");
                Execute("var clearTimeout = clearInterval;");
            }
            catch (Exception ex) {
                throw;
            }
        }