]> git.immae.eu Git - github/fretlink/purs-loader.git/blame - src/Loader.purs
Merge pull request #19 from ethul/topic/issue-17
[github/fretlink/purs-loader.git] / src / Loader.purs
CommitLineData
c194f84c 1module PursLoader.Loader
1983893b 2 ( Effects()
c194f84c 3 , loader
4 , loaderFn
5 ) where
6
7import Control.Monad.Aff (Aff(), runAff)
8import Control.Monad.Eff (Eff())
9import Control.Monad.Eff.Class (liftEff)
10import Control.Monad.Eff.Exception (error)
11
0e1221d7 12import Data.Array ((!!), concat)
c194f84c 13import Data.Function (Fn2(), mkFn2)
14import Data.Maybe (Maybe(..), fromMaybe, maybe)
0e1221d7 15import Data.String (joinWith)
1983893b 16import Data.String.Regex (match, noFlags, regex)
c194f84c 17
18import PursLoader.ChildProcess (ChildProcess(), spawn)
0e1221d7 19import PursLoader.FS (FS(), writeFileUtf8)
20import PursLoader.Glob (Glob(), globAll)
1983893b 21import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, query)
0e1221d7 22import PursLoader.LoaderUtil (parseQuery)
23import PursLoader.Options (loaderFFIOption, loaderSrcOption, pscOptions)
c194f84c 24
0e1221d7 25type Effects eff = (cp :: ChildProcess, fs :: FS, glob :: Glob, loader :: Loader | eff)
c194f84c 26
27moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }
28
1983893b 29pscCommand = "psc"
c194f84c 30
0e1221d7 31psciCommand = "psci"
32
33psciFilename = ".psci"
34
c194f84c 35(!!!) = flip (!!)
36
0e1221d7 37foreign import cwd "var cwd = process.cwd();" :: String
38
39foreign import relative """
40function relative(from) {
41 return function(to){
42 var path = require('path');
43 return path.relative(from, to);
44 };
45}
46""" :: String -> String -> String
47
48mkPsci :: [[String]] -> [[String]] -> String
49mkPsci srcs ffis = joinWith "\n" ((loadModule <$> concat srcs) <> (loadForeign <$> concat ffis))
50 where
51 loadModule :: String -> String
52 loadModule a = ":m " ++ relative cwd a
53
54 loadForeign :: String -> String
55 loadForeign a = ":f " ++ relative cwd a
56
1983893b 57loader' :: forall eff. LoaderRef -> String -> Aff (Effects eff) (Maybe String)
c194f84c 58loader' ref source = do
59 liftEff $ cacheable ref
60
0e1221d7 61 let parsed = parseQuery $ query ref
1983893b 62 srcs = fromMaybe [] (loaderSrcOption parsed)
0e1221d7 63 ffis = fromMaybe [] (loaderFFIOption parsed)
1983893b 64 opts = pscOptions parsed
c194f84c 65
1983893b 66 spawn pscCommand (srcs <> opts)
0e1221d7 67
68 srcss <- globAll srcs
69 ffiss <- globAll ffis
70
71 let psciFile = mkPsci srcss ffiss
72
73 writeFileUtf8 psciFilename psciFile
74
75 let moduleName = match moduleRegex source >>= (!!!) 1
76 result = (\a -> "module.exports = require('" ++ a ++ "');") <$> moduleName
77
1983893b 78 return result
c194f84c 79
1983893b 80loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit
c194f84c 81loader ref source = do
82 callback <- async ref
83 runAff (\e -> callback (Just e) "")
1983893b 84 (maybe (callback (Just (error "Loader has failed to run")) "")
c194f84c 85 (callback Nothing))
86 (loader' ref source)
87
1983893b 88loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit)
c194f84c 89loaderFn = mkFn2 loader