]> git.immae.eu Git - github/fretlink/purs-loader.git/blob - src/Loader.purs
Bumping version number to 0.3.0
[github/fretlink/purs-loader.git] / src / Loader.purs
1 module PursLoader.Loader
2 ( Effects()
3 , loader
4 , loaderFn
5 ) where
6
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)
11
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)
17
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)
24
25 type Effects eff = (cp :: ChildProcess, fs :: FS, glob :: Glob, loader :: Loader | eff)
26
27 moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }
28
29 pscCommand = "psc"
30
31 psciCommand = "psci"
32
33 psciFilename = ".psci"
34
35 (!!!) = flip (!!)
36
37 foreign import cwd "var cwd = process.cwd();" :: String
38
39 foreign import relative """
40 function relative(from) {
41 return function(to){
42 var path = require('path');
43 return path.relative(from, to);
44 };
45 }
46 """ :: String -> String -> String
47
48 mkPsci :: [[String]] -> [[String]] -> String
49 mkPsci 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
57 loader' :: forall eff. LoaderRef -> String -> Aff (Effects eff) (Maybe String)
58 loader' ref source = do
59 liftEff $ cacheable ref
60
61 let parsed = parseQuery $ query ref
62 srcs = fromMaybe [] (loaderSrcOption parsed)
63 ffis = fromMaybe [] (loaderFFIOption parsed)
64 opts = pscOptions parsed
65
66 spawn pscCommand (srcs <> opts)
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
78 return result
79
80 loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit
81 loader ref source = do
82 callback <- async ref
83 runAff (\e -> callback (Just e) "")
84 (maybe (callback (Just (error "Loader has failed to run")) "")
85 (callback Nothing))
86 (loader' ref source)
87
88 loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit)
89 loaderFn = mkFn2 loader