module PursLoader.Loader ( Effects() , loader , loaderFn ) where import Control.Monad.Aff (Aff(), runAff) import Control.Monad.Eff (Eff()) import Control.Monad.Eff.Class (liftEff) import Control.Monad.Eff.Exception (error) import Data.Array ((!!)) import Data.Function (Fn2(), mkFn2) import Data.Maybe (Maybe(..), fromMaybe, maybe) import Data.String.Regex (match, noFlags, regex) import PursLoader.ChildProcess (ChildProcess(), spawn) import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, query) import PursLoader.LoaderUtil (getRemainingRequest, parseQuery) import PursLoader.Options (loaderSrcOption, pscOptions) type Effects eff = (loader :: Loader, cp :: ChildProcess | eff) moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true } pscCommand = "psc" (!!!) = flip (!!) loader' :: forall eff. LoaderRef -> String -> Aff (Effects eff) (Maybe String) loader' ref source = do liftEff $ cacheable ref let request = getRemainingRequest ref parsed = parseQuery $ query ref srcs = fromMaybe [] (loaderSrcOption parsed) opts = pscOptions parsed moduleName = match moduleRegex source >>= (!!!) 1 result = (\a -> "module.exports = require('" ++ a ++ "');") <$> moduleName spawn pscCommand (srcs <> opts) return result loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit loader ref source = do callback <- async ref runAff (\e -> callback (Just e) "") (maybe (callback (Just (error "Loader has failed to run")) "") (callback Nothing)) (loader' ref source) loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit) loaderFn = mkFn2 loader