1414module Node.ChildProcess
1515 ( Handle
1616 , ChildProcess
17+ , toEventEmitter
18+ , closeH
19+ , disconnectH
20+ , errorH
21+ , exitH
22+ , messageH
23+ , spawnH
1724 , stdin
1825 , stdout
1926 , stderr
@@ -25,11 +32,6 @@ module Node.ChildProcess
2532 , Error
2633 , toStandardError
2734 , Exit (..)
28- , onExit
29- , onClose
30- , onDisconnect
31- , onMessage
32- , onError
3335 , spawn
3436 , SpawnOptions
3537 , defaultSpawnOptions
@@ -51,31 +53,64 @@ module Node.ChildProcess
5153
5254import Prelude
5355
54- import Control.Alt ((<|>))
5556import Data.Function.Uncurried (Fn2 , runFn2 )
5657import Data.Maybe (Maybe (..), fromMaybe , maybe )
57- import Data.Nullable (Nullable , toNullable , toMaybe )
58+ import Data.Nullable (Nullable , toMaybe , toNullable )
5859import Data.Posix (Pid , Gid , Uid )
5960import Data.Posix.Signal (Signal )
6061import Data.Posix.Signal as Signal
6162import Effect (Effect )
6263import Effect.Exception as Exception
63- import Effect.Exception.Unsafe ( unsafeThrow )
64+ import Effect.Uncurried ( EffectFn2 , mkEffectFn1 , mkEffectFn2 )
6465import Foreign (Foreign )
6566import Foreign.Object (Object )
6667import Node.Buffer (Buffer )
6768import Node.Encoding (Encoding , encodingToNode )
69+ import Node.EventEmitter (EventEmitter , EventHandle (..))
70+ import Node.EventEmitter.UtilTypes (EventHandle0 , EventHandle1 )
6871import Node.FS as FS
69- import Node.Stream (Readable , Writable , Stream )
72+ import Node.Stream (Readable , Stream , Writable )
73+ import Partial.Unsafe (unsafeCrashWith )
7074import Unsafe.Coerce (unsafeCoerce )
7175
7276-- | A handle for inter-process communication (IPC).
7377foreign import data Handle :: Type
7478
7579-- | Opaque type returned by `spawn`, `fork` and `exec`.
7680-- | Needed as input for most methods in this module.
81+ -- |
82+ -- | `ChildProcess` extends `EventEmitter`
7783newtype ChildProcess = ChildProcess ChildProcessRec
7884
85+ toEventEmitter :: ChildProcess -> EventEmitter
86+ toEventEmitter = unsafeCoerce
87+
88+ closeH :: EventHandle ChildProcess (Exit -> Effect Unit ) (EffectFn2 (Nullable Int ) (Nullable String ) Unit )
89+ closeH = EventHandle " close" \cb -> mkEffectFn2 \code signal ->
90+ case toMaybe code, toMaybe signal >>= Signal .fromString of
91+ Just c, _ -> cb $ Normally c
92+ _, Just s -> cb $ BySignal s
93+ _, _ -> unsafeCrashWith $ " Impossible. 'close' event did not get an exit code or kill signal: " <> show code <> " ; " <> show signal
94+
95+ disconnectH :: EventHandle0 ChildProcess
96+ disconnectH = EventHandle " disconnect" identity
97+
98+ errorH :: EventHandle1 ChildProcess Error
99+ errorH = EventHandle " error" mkEffectFn1
100+
101+ exitH :: EventHandle ChildProcess (Exit -> Effect Unit ) (EffectFn2 (Nullable Int ) (Nullable String ) Unit )
102+ exitH = EventHandle " exitH" \cb -> mkEffectFn2 \code signal ->
103+ case toMaybe code, toMaybe signal >>= Signal .fromString of
104+ Just c, _ -> cb $ Normally c
105+ _, Just s -> cb $ BySignal s
106+ _, _ -> unsafeCrashWith $ " Impossible. 'exit' event did not get an exit code or kill signal: " <> show code <> " ; " <> show signal
107+
108+ messageH :: EventHandle ChildProcess (Foreign -> Maybe Handle -> Effect Unit ) (EffectFn2 Foreign (Nullable Handle ) Unit )
109+ messageH = EventHandle " message" \cb -> mkEffectFn2 \a b -> cb a $ toMaybe b
110+
111+ spawnH :: EventHandle0 ChildProcess
112+ spawnH = EventHandle " spawn" identity
113+
79114runChildProcess :: ChildProcess -> ChildProcessRec
80115runChildProcess (ChildProcess r) = r
81116
@@ -165,68 +200,6 @@ instance showExit :: Show Exit where
165200 show (Normally x) = " Normally " <> show x
166201 show (BySignal sig) = " BySignal " <> show sig
167202
168- mkExit :: Nullable Int -> Nullable String -> Exit
169- mkExit code signal =
170- case fromCode code <|> fromSignal signal of
171- Just e -> e
172- Nothing -> unsafeThrow " Node.ChildProcess.mkExit: Invalid arguments"
173- where
174- fromCode = toMaybe >>> map Normally
175- fromSignal = toMaybe >=> Signal .fromString >>> map BySignal
176-
177- -- | Handle the `"exit"` signal.
178- onExit
179- :: ChildProcess
180- -> (Exit -> Effect Unit )
181- -> Effect Unit
182- onExit = mkOnExit mkExit
183-
184- foreign import mkOnExit
185- :: (Nullable Int -> Nullable String -> Exit )
186- -> ChildProcess
187- -> (Exit -> Effect Unit )
188- -> Effect Unit
189-
190- -- | Handle the `"close"` signal.
191- onClose
192- :: ChildProcess
193- -> (Exit -> Effect Unit )
194- -> Effect Unit
195- onClose = mkOnClose mkExit
196-
197- foreign import mkOnClose
198- :: (Nullable Int -> Nullable String -> Exit )
199- -> ChildProcess
200- -> (Exit -> Effect Unit )
201- -> Effect Unit
202-
203- -- | Handle the `"message"` signal.
204- onMessage
205- :: ChildProcess
206- -> (Foreign -> Maybe Handle -> Effect Unit )
207- -> Effect Unit
208- onMessage = mkOnMessage Nothing Just
209-
210- foreign import mkOnMessage
211- :: forall a
212- . Maybe a
213- -> (a -> Maybe a )
214- -> ChildProcess
215- -> (Foreign -> Maybe Handle -> Effect Unit )
216- -> Effect Unit
217-
218- -- | Handle the `"disconnect"` signal.
219- foreign import onDisconnect
220- :: ChildProcess
221- -> Effect Unit
222- -> Effect Unit
223-
224- -- | Handle the `"error"` signal.
225- foreign import onError
226- :: ChildProcess
227- -> (Error -> Effect Unit )
228- -> Effect Unit
229-
230203-- | Spawn a child process. Note that, in the event that a child process could
231204-- | not be spawned (for example, if the executable was not found) this will
232205-- | not throw an error. Instead, the `ChildProcess` will be created anyway,
0 commit comments