]> git.immae.eu Git - github/fretlink/purs-loader.git/blame - src/PursLoader/Loader.purs
Bumping version number to 0.6.0-beta.1
[github/fretlink/purs-loader.git] / src / PursLoader / Loader.purs
CommitLineData
c194f84c 1module PursLoader.Loader
1983893b 2 ( Effects()
c194f84c 3 , loader
4 , loaderFn
5 ) where
6
46039343 7import Prelude (Unit(), ($), (>>=), (<$>), (<*>), (++), bind, const, id, pure, unit)
03b840cb 8
46039343 9import Control.Apply ((*>))
63d6a244 10import Control.Bind (join)
46039343 11import Control.Monad.Eff (Eff(), foreachE)
63d6a244 12import Control.Monad.Eff.Exception (Error(), error)
c194f84c 13
63d6a244 14import Data.Array ((!!))
46039343 15import Data.Bifunctor (lmap)
16import Data.Either (Either(..), either)
17import Data.Foreign.Class (read)
c194f84c 18import Data.Function (Fn2(), mkFn2)
63d6a244 19import Data.Maybe (Maybe(..), maybe)
46039343 20import Data.Nullable (toMaybe)
63d6a244 21import Data.String.Regex (Regex(), match, noFlags, regex)
22
23import Unsafe.Coerce (unsafeCoerce)
24
25import PursLoader.LoaderRef
46039343 26 ( AsyncCallback()
27 , LoaderRef()
63d6a244 28 , Loader()
29 , async
30 , cacheable
31 , query
32 , clearDependencies
33 , addDependency
34 , resourcePath
35 )
c194f84c 36
3afbe2fd 37import PursLoader.Debug (debug)
0e1221d7 38import PursLoader.LoaderUtil (parseQuery)
46039343 39import PursLoader.Options (Options(..))
63d6a244 40import PursLoader.Path (dirname, relative)
46039343 41import PursLoader.Plugin as Plugin
c194f84c 42
63d6a244 43type Effects eff = (loader :: Loader | eff)
c194f84c 44
63d6a244 45loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit
46loader ref source = do
47 callback <- async ref
3610dff1 48
63d6a244 49 cacheable ref
c194f84c 50
3afbe2fd 51 debug "Invoke PureScript plugin compilation"
52
46039343 53 pluginContext.compile (compile callback)
63d6a244 54 where
46039343 55 pluginContext :: Plugin.Context (Effects eff)
63d6a244 56 pluginContext = (unsafeCoerce ref).purescriptWebpackPluginContext
c194f84c 57
46039343 58 compile :: AsyncCallback eff -> Plugin.Compile (Effects eff)
59 compile callback error' { srcMap, ffiMap, graph } = do
60 clearDependencies ref
61
3afbe2fd 62 either (const $ pure unit) (\a -> debug ("Adding PureScript dependency " ++ a)) name
63
46039343 64 addDependency ref (resourcePath ref)
65
66 either (\err -> callback (Just err) "") id
67 (handle <$> name <*> dependencies <*> exports)
68 where
69 handle :: String -> Array String -> String -> Eff (Effects eff) Unit
70 handle name' deps res = do
3afbe2fd 71 debug ("Adding PureScript transitive dependencies for " ++ name')
46039343 72 addTransitive name'
73 foreachE deps addTransitive
74 callback (toMaybe error') res
75
76 exports :: Either Error String
77 exports = (\a b -> "module.exports = require('" ++ a ++ "')['" ++ b ++ "'];") <$> path <*> name
78
79 dependencies :: Either Error (Array String)
80 dependencies = name >>= Plugin.dependenciesOf graph
81
82 addTransitive :: String -> Eff (Effects eff) Unit
83 addTransitive dep = addDep (Plugin.get srcMap dep) *> addDep (Plugin.get ffiMap dep)
84 where
85 addDep :: Maybe String -> Eff (Effects eff) Unit
86 addDep = maybe (pure unit) (addDependency ref)
87
88 name :: Either Error String
89 name =
90 maybe (Left $ error "Failed to parse module name") Right
91 (join $ match re source >>= \as -> as !! 1)
92 where
93 re :: Regex
94 re = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }
95
96 path :: Either Error String
97 path = (\(Options opts) -> relative resourceDir opts.bundleOutput) <$> options
98 where
99 options :: Either Error Options
100 options =
101 lmap (const $ error "Failed to parse loader query")
102 (read $ parseQuery (query ref))
103
104 resourceDir :: String
105 resourceDir = dirname (resourcePath ref)
c194f84c 106
1983893b 107loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit)
c194f84c 108loaderFn = mkFn2 loader