-
-
Notifications
You must be signed in to change notification settings - Fork 43
/
JavaScriptEventLoop.swift
59 lines (53 loc) · 1.69 KB
/
JavaScriptEventLoop.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import _CJavaScriptEventLoop
import JavaScriptKit
public enum JavaScriptEventLoop {
public static func install() {
installTaskEnqueueHook()
}
public static func runAsync(_ asyncFun: @escaping () async throws -> ()) rethrows {
try _runAsync(asyncFun)
}
}
public extension JSPromise {
func await() async throws -> JSValue {
await try withUnsafeThrowingContinuation { [self] continuation in
self.then(
success: {
continuation.resume(returning: $0)
return JSValue.undefined
},
failure: {
continuation.resume(throwing: $0)
return JSValue.undefined
}
)
}
}
}
@_silgen_name("swift_run_async")
func _runAsync(_ asyncFun: @escaping () async throws -> ()) rethrows
private func getPromise(from context: UnsafeMutablePointer<EventLoopContext>) -> JSPromise {
let promise: JSPromise
if let cached = context.pointee.Promise {
promise = Unmanaged.fromOpaque(cached).takeUnretainedValue()
} else {
promise = JSPromise(resolver: { resolver -> Void in
resolver(.success(.undefined))
})
let pointer = Unmanaged.passRetained(promise).retain().toOpaque()
context.pointee.Promise = pointer
}
return promise
}
#if arch(wasm32)
@_cdecl("registerEventLoopHook")
func registerEventLoopHook(
_ callback: @convention(c) @escaping (UnsafeMutablePointer<EventLoopContext>) -> Void,
_ context: UnsafeMutablePointer<EventLoopContext>
) {
getPromise(from: context).then { _ in
callback(context)
return JSValue.undefined
}
}
#endif