2 | import Data.Linear.Ref1
3 | import public JS.Util
4 | import public JS.Promise
5 | import public IO.Async
6 | import public IO.Async.Logging
7 | import public IO.Async.Loop
8 | import public IO.Async.Loop.TimerH
19 | running : IORef Bool
22 | queue : IORef (SnocList Task)
27 | spawnImpl : JS -> Task -> IO1 ()
29 | export %inline covering
35 | app : Async JS [] () -> IO ()
39 | runAsyncWith (J r q) prog (\_ => putStrLn "Done. Shutting down")
45 | %foreign "javascript:lambda:(m,f,w) => setTimeout(f, Number(m))"
46 | prim__setTimeout : Integer -> PrimIO () -> PrimIO Bits32
48 | %foreign "javascript:lambda:(i,w) => clearTimeout(i)"
49 | prim__clearTimeout : Bits32 -> PrimIO ()
53 | primWait s cl act t =
54 | let ms := toNano cl `div` 1_000_000
55 | x # t := ffi (prim__setTimeout ms (primRun act)) t
56 | in ffi (prim__clearTimeout x) # t
65 | promise : Has JSErr es => Promise a -> Async JS es a
67 | primAsync_ $
\f => ioToF1 $
ignore $
71 | (runIO . f . Left . inject . Caught)
78 | checkQueue : JS -> IO1 ()
81 | run : JS -> List Task -> IO1 ()
82 | run s [] t = checkQueue s t
84 | case runFbr s x t of
85 | Cont fst # t => let _ # t := mod1 s.queue (:< fst) t in run s xs t
86 | Done # t => run s xs t
90 | let sa # t := read1 s.queue t
91 | _ # t := write1 s.queue [<] t
92 | in case sa <>> [] of
93 | [] => write1 s.running False t
97 | let _ # t := mod1 s.queue (:<x) t
98 | False # t := read1 s.running t | True # t => () # t
99 | _ # t := write1 s.running True t
106 | parameters {auto lgs : Loggable JS JSErr}
109 | jsunerr : (dflt : t) -> Async JS [JSErr] t -> Async JS [] t
113 | jsunerrMaybe : Async JS [JSErr] t -> Async JS [] (Maybe t)
114 | jsunerrMaybe = unerrMaybe
117 | jslogErrs : Async JS [JSErr] () -> Async JS [] ()
118 | jslogErrs = jsunerr ()