]> git.immae.eu Git - github/fretlink/purs-loader.git/blame - src/PursLoader/Loader.purs
Merge branch 'master' into topic/stderr
[github/fretlink/purs-loader.git] / src / PursLoader / Loader.purs
CommitLineData
c194f84c 1module PursLoader.Loader
1983893b 2 ( Effects()
1c49c88e 3 , Effects_()
c194f84c 4 , loader
5 , loaderFn
6 ) where
7
cb2f4c88 8import Prelude (Unit(), ($), (>>=), (<$>), (<*>), (++), (<<<), bind, const, id, pure, unit, void)
03b840cb 9
63d6a244 10import Control.Bind (join)
46039343 11import Control.Monad.Eff (Eff(), foreachE)
1c49c88e 12import Control.Monad.Eff.Console (CONSOLE())
13import Control.Monad.Eff.Exception (EXCEPTION(), Error(), error, message)
c194f84c 14
63d6a244 15import Data.Array ((!!))
46039343 16import Data.Either (Either(..), either)
c194f84c 17import Data.Function (Fn2(), mkFn2)
cb2f4c88 18import Data.Maybe (maybe)
46039343 19import Data.Nullable (toMaybe)
63d6a244 20import Data.String.Regex (Regex(), match, noFlags, regex)
21
1c49c88e 22import Node.Encoding (Encoding(UTF8))
23import Node.Process (stderr)
24import Node.Stream (writeString)
25
63d6a244 26import Unsafe.Coerce (unsafeCoerce)
27
28import PursLoader.LoaderRef
46039343 29 ( AsyncCallback()
30 , LoaderRef()
63d6a244 31 , Loader()
32 , async
33 , cacheable
63d6a244 34 , addDependency
35 , resourcePath
36 )
c194f84c 37
3afbe2fd 38import PursLoader.Debug (debug)
87145c4d 39import PursLoader.Path (dirname, joinPath, relative)
46039343 40import PursLoader.Plugin as Plugin
c194f84c 41
1c49c88e 42type Effects eff = (console :: CONSOLE, err :: EXCEPTION | eff)
43
44type Effects_ eff = Effects (loader :: Loader | eff)
c194f84c 45
1c49c88e 46loader :: forall eff. LoaderRef -> String -> Eff (Effects_ eff) Unit
63d6a244 47loader ref source = do
48 callback <- async ref
3610dff1 49
63d6a244 50 cacheable ref
c194f84c 51
3afbe2fd 52 debug "Invoke PureScript plugin compilation"
53
46039343 54 pluginContext.compile (compile callback)
63d6a244 55 where
1c49c88e 56 pluginContext :: Plugin.Context (Effects_ eff)
63d6a244 57 pluginContext = (unsafeCoerce ref).purescriptWebpackPluginContext
c194f84c 58
1c49c88e 59 compile :: AsyncCallback (Effects eff) -> Plugin.Compile (Effects_ eff)
cb2f4c88 60 compile callback error' graph output = do
3afbe2fd 61 either (const $ pure unit) (\a -> debug ("Adding PureScript dependency " ++ a)) name
62
46039343 63 addDependency ref (resourcePath ref)
64
1c49c88e 65 void $ writeString stderr UTF8 output (pure unit)
66
67 maybe (pure unit) (\a -> void $ writeString stderr UTF8 (message a) (pure unit)) (toMaybe error')
68
69 either (const $ callback (pure fixedError) "") id
46039343 70 (handle <$> name <*> dependencies <*> exports)
71 where
1c49c88e 72 fixedError :: Error
73 fixedError = error "PureScript compilation has failed."
74
75 handle :: String -> Array String -> String -> Eff (Effects_ eff) Unit
46039343 76 handle name' deps res = do
845f3ec3 77 debug ("Adding PureScript dependencies for " ++ name')
78 foreachE deps (addDependency ref)
b1b6e146 79 debug "Generated loader result"
80 debug res
1c49c88e 81 callback (const fixedError <$> toMaybe error') res
46039343 82
83 exports :: Either Error String
87145c4d 84 exports =
85 if pluginContext.options.bundle
86 then bundleExport <$> name
87 else moduleExport <<< modulePath <$> name
88 where
89 bundleExport :: String -> String
90 bundleExport name' = "module.exports = require('" ++ path ++ "')['" ++ name' ++ "'];"
91 where
92 path :: String
93 path = relative resourceDir pluginContext.options.bundleOutput
46039343 94
87145c4d 95 moduleExport :: String -> String
96 moduleExport path = "module.exports = require('" ++ path ++ "');"
46039343 97
87145c4d 98 modulePath :: String -> String
99 modulePath = relative resourceDir <<< joinPath pluginContext.options.output
100
101 resourceDir :: String
102 resourceDir = dirname (resourcePath ref)
46039343 103
104 dependencies :: Either Error (Array String)
845f3ec3 105 dependencies = Plugin.dependenciesOf graph (resourcePath ref)
46039343 106
107 name :: Either Error String
108 name =
109 maybe (Left $ error "Failed to parse module name") Right
110 (join $ match re source >>= \as -> as !! 1)
111 where
112 re :: Regex
113 re = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }
114
1c49c88e 115loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects_ eff) Unit)
c194f84c 116loaderFn = mkFn2 loader