Created
July 4, 2023 06:33
-
-
Save Dubiy/ed4ada7bae6f8557c1d7ce9ace4dd1bf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Jint; | |
using UnityEngine; | |
using System; | |
using System.IO; | |
using System.Net.Http; | |
using System.Threading.Tasks; | |
using System.Collections.Generic; | |
using System.Timers; | |
public class RunJs : MonoBehaviour | |
{ | |
private static Engine engine; | |
private static Dictionary<int, Timer> timers; | |
private static int timerIdCounter = 0; | |
void Start() | |
{ | |
engine = new Engine(); | |
timers = new Dictionary<int, Timer>(); // Initialize the timers dictionary | |
engine.SetValue("console",typeof(Debug)); | |
engine.Execute("window = {};"); | |
engine.Execute("global = {};"); | |
engine.SetValue("setTimeout", new Action<Action, double>(SetTimeout)); | |
// engine.SetValue("fetch", new Func<RequestObj, FetchResponse>(Fetch)); | |
engine.SetValue("XMLHttpRequest", typeof(XMLHTTPRequest)); | |
// var source = new StreamReader(Application.dataPath + "/Resources/" + "JSWrapper.bundle.js"); | |
// string script = source.ReadToEnd(); | |
// source.Close(); | |
// engine.Execute(script); | |
// engine.Evaluate("window.bladeSdk.init('...apiKey...', 'dappcode', 'initBladeSdkJS1')").ToObject(); | |
engine.Execute(@" | |
(() => { | |
return new Promise((resolve, reject) => { | |
var xhr = new XMLHttpRequest(); | |
xhr.onreadystatechange = function() { | |
if (xhr.readyState === 4 && xhr.status === 200) { | |
console.log(xhr.responseText); | |
} else { | |
console.log(JSON.stringify(xhr)); | |
} | |
// setTimeout(function() { | |
// resolve(`resolve from timeout FAILS ${JSON.stringify(xhr)}`); | |
// }, 0); | |
}; | |
// setTimeout(function() { | |
// resolve(`resolve from timeout OK`); | |
// }, 0); | |
xhr.open('GET', 'https://mainnet-public.mirrornode.hedera.com/api/v1/accounts/0.0.3333', true); | |
xhr.onload = function() { | |
console.log('on Load invoked'); | |
setTimeout(function() { | |
resolve(`resolve from timeout FAILS here too`); | |
}, 0); | |
} | |
xhr.send(); | |
}) | |
})() | |
.then(res => { | |
console.log(`PROMISE resolve: ${res}`) | |
}) | |
.catch(res => { | |
console.log(`PROMISE reject: ${res}`) | |
}) | |
"); | |
static FetchResponse Fetch(RequestObj request) | |
{ | |
var url = request.url; | |
var fetchResponse = new FetchResponse(); | |
Task.Run(async () => | |
{ | |
try | |
{ | |
using (var httpClient = new HttpClient()) | |
{ | |
var response = await httpClient.GetAsync(url); | |
var content = await response.Content.ReadAsStringAsync(); | |
var result = new | |
{ | |
ok = response.IsSuccessStatusCode, | |
status = (int)response.StatusCode, | |
statusText = response.StatusCode.ToString(), | |
text = new Func<string>(() => content), | |
json = new Func<string>(() => content) | |
}; | |
fetchResponse.Resolve(result); | |
} | |
} | |
catch (Exception e) | |
{ | |
var result = new | |
{ | |
ok = false, | |
status = 0, | |
statusText = e.Message, | |
text = new Func<string>(() => string.Empty), | |
json = new Func<string>(() => string.Empty) | |
}; | |
fetchResponse.Reject(result); | |
} | |
}); | |
return fetchResponse; | |
} | |
} | |
static void SetTimeout(Action callback, double delay) | |
{ | |
Timer timer = new Timer(delay+1); | |
timer.Elapsed += (sender, args) => | |
{ | |
callback.Invoke(); | |
timer.Stop(); | |
timer.Dispose(); | |
}; | |
int timerId = timerIdCounter++; | |
timers[timerId] = timer; | |
timer.Start(); | |
} | |
} | |
public class RequestObj | |
{ | |
public string url { get; set; } | |
public string method { get; set; } = "get"; | |
public override string ToString() | |
{ | |
return $"url: {url}, method: {method}"; | |
} | |
} | |
class FetchResponse | |
{ | |
private Action<object> resolveCallback; | |
private Action<object> rejectCallback; | |
public void Resolve(object result) | |
{ | |
resolveCallback?.Invoke(result); | |
} | |
public void Reject(object error) | |
{ | |
rejectCallback?.Invoke(error); | |
} | |
// set callbacks. | |
// TODO: chain callbacks | |
public FetchResponse Then(Action<object> onResolved) | |
{ | |
resolveCallback = onResolved; | |
return this; | |
} | |
public FetchResponse Catch(Action<object> onRejected) | |
{ | |
rejectCallback = onRejected; | |
return this; | |
} | |
} | |
public class XMLHTTPRequest | |
{ | |
private HttpClient client; | |
private HttpRequestMessage request; | |
private HttpResponseMessage response; | |
private Action onReadyStateChange; | |
private Action onLoad; | |
private Action onError; | |
private Action onTimeout; | |
private Action onAbort; | |
private bool isPolling; | |
public XMLHTTPRequest() | |
{ | |
client = new HttpClient(); | |
request = new HttpRequestMessage(); | |
isPolling = false; | |
} | |
public void open(string method, string url, bool async = true) | |
{ | |
request.Method = new HttpMethod(method); | |
request.RequestUri = new Uri(url); | |
} | |
public void send(string bodyInit = "") | |
{ | |
response = client.SendAsync(request).GetAwaiter().GetResult(); | |
StartPolling(); | |
} | |
private async void StartPolling() | |
{ | |
int delay = 100; | |
int timeout = 30000; | |
isPolling = true; | |
while (isPolling) | |
{ | |
await Task.Delay(delay); // Adjust the polling interval as needed | |
timeout -= delay; | |
if ((int)(response?.StatusCode ?? 0) > 0) { | |
Debug.Log("response code: " + response?.StatusCode); | |
isPolling = false; | |
Debug.Log("onLoad?: " + onLoad); | |
onReadyStateChange?.Invoke(); | |
onLoad?.Invoke(); | |
} | |
// TODO on error | |
if (timeout <= 0) { | |
onTimeout?.Invoke(); | |
onAbort?.Invoke(); | |
} | |
} | |
} | |
public void abort() | |
{ | |
isPolling = false; | |
request.Dispose(); | |
onAbort?.Invoke(); | |
} | |
public string getAllResponseHeaders() { | |
return ""; | |
} | |
public string responseText | |
{ | |
get | |
{ | |
return response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); | |
} | |
} | |
public int status | |
{ | |
get | |
{ | |
return (int)(response?.StatusCode ?? 0); | |
} | |
} | |
public int readyState | |
{ | |
get | |
{ | |
return isPolling ? 3 : 4; | |
} | |
} | |
public Action onreadystatechange | |
{ | |
get | |
{ | |
return onReadyStateChange; | |
} | |
set | |
{ | |
Debug.Log("onreadystatechange set"); | |
onReadyStateChange = value; | |
} | |
} | |
public Action onload | |
{ | |
get | |
{ | |
return onLoad; | |
} | |
set | |
{ | |
Debug.Log("onload set"); | |
onLoad = value; | |
} | |
} | |
public Action onerror | |
{ | |
get | |
{ | |
return onError; | |
} | |
set | |
{ | |
Debug.Log("onerror set"); | |
onError = value; | |
} | |
} | |
public Action ontimeout | |
{ | |
get | |
{ | |
return onTimeout; | |
} | |
set | |
{ | |
Debug.Log("ontimeout set"); | |
onTimeout = value; | |
} | |
} | |
public Action onabort | |
{ | |
get | |
{ | |
return onAbort; | |
} | |
set | |
{ | |
Debug.Log("onabort set"); | |
onAbort = value; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment