]> git.immae.eu Git - github/fretlink/purs-loader.git/blame - src/PursLoader/Loader.purs
Bumping version number to 0.6.0-beta.2
[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
b1b6e146 74 debug "Generated loader result"
75 debug res
46039343 76 callback (toMaybe error') res
77
78 exports :: Either Error String
79 exports = (\a b -> "module.exports = require('" ++ a ++ "')['" ++ b ++ "'];") <$> path <*> name
80
81 dependencies :: Either Error (Array String)
82 dependencies = name >>= Plugin.dependenciesOf graph
83
84 addTransitive :: String -> Eff (Effects eff) Unit
85 addTransitive dep = addDep (Plugin.get srcMap dep) *> addDep (Plugin.get ffiMap dep)
86 where
87 addDep :: Maybe String -> Eff (Effects eff) Unit
88 addDep = maybe (pure unit) (addDependency ref)
89
90 name :: Either Error String
91 name =
92 maybe (Left $ error "Failed to parse module name") Right
93 (join $ match re source >>= \as -> as !! 1)
94 where
95 re :: Regex
96 re = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }
97
98 path :: Either Error String
99 path = (\(Options opts) -> relative resourceDir opts.bundleOutput) <$> options
100 where
101 options :: Either Error Options
102 options =
103 lmap (const $ error "Failed to parse loader query")
104 (read $ parseQuery (query ref))
105
106 resourceDir :: String
107 resourceDir = dirname (resourcePath ref)
c194f84c 108
1983893b 109loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit)
c194f84c 110loaderFn = mkFn2 loader