1 module PursLoader.Loader
7 import Control.Monad.Aff (Aff(), runAff)
8 import Control.Monad.Eff (Eff())
9 import Control.Monad.Eff.Class (liftEff)
10 import Control.Monad.Eff.Exception (error)
12 import Data.Array ((!!), concat)
13 import Data.Function (Fn2(), mkFn2)
14 import Data.Maybe (Maybe(..), fromMaybe, maybe)
15 import Data.String (joinWith)
16 import Data.String.Regex (match, noFlags, regex)
18 import PursLoader.ChildProcess (ChildProcess(), spawn)
19 import PursLoader.FS (FS(), writeFileUtf8)
20 import PursLoader.Glob (Glob(), globAll)
21 import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, query)
22 import PursLoader.LoaderUtil (parseQuery)
23 import PursLoader.Options (loaderFFIOption, loaderSrcOption, pscOptions)
25 type Effects eff = (cp :: ChildProcess, fs :: FS, glob :: Glob, loader :: Loader | eff)
27 moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }
33 psciFilename = ".psci"
37 foreign import cwd "var cwd = process.cwd();" :: String
39 foreign import relative """
40 function relative(from) {
42 var path = require('path');
43 return path.relative(from, to);
46 """ :: String -> String -> String
48 mkPsci :: [[String]] -> [[String]] -> String
49 mkPsci srcs ffis = joinWith "\n" ((loadModule <$> concat srcs) <> (loadForeign <$> concat ffis))
51 loadModule :: String -> String
52 loadModule a = ":m " ++ relative cwd a
54 loadForeign :: String -> String
55 loadForeign a = ":f " ++ relative cwd a
57 loader' :: forall eff. LoaderRef -> String -> Aff (Effects eff) (Maybe String)
58 loader' ref source = do
59 liftEff $ cacheable ref
61 let parsed = parseQuery $ query ref
62 srcs = fromMaybe [] (loaderSrcOption parsed)
63 ffis = fromMaybe [] (loaderFFIOption parsed)
64 opts = pscOptions parsed
66 spawn pscCommand (srcs <> opts)
71 let psciFile = mkPsci srcss ffiss
73 writeFileUtf8 psciFilename psciFile
75 let moduleName = match moduleRegex source >>= (!!!) 1
76 result = (\a -> "module.exports = require('" ++ a ++ "');") <$> moduleName
80 loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit
81 loader ref source = do
83 runAff (\e -> callback (Just e) "")
84 (maybe (callback (Just (error "Loader has failed to run")) "")
88 loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit)
89 loaderFn = mkFn2 loader