aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Loader.purs
blob: 0235da91ed3df950fb52f963f0feb99293ca6254 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
module PursLoader.Loader
  ( Effects()
  , loader
  , loaderFn
  ) where

import Control.Monad.Aff (Aff(), runAff)
import Control.Monad.Eff (Eff())
import Control.Monad.Eff.Class (liftEff)
import Control.Monad.Eff.Exception (error)

import Data.Array ((!!))
import Data.Function (Fn2(), mkFn2)
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.String.Regex (match, noFlags, regex)

import PursLoader.ChildProcess (ChildProcess(), spawn)
import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, query)
import PursLoader.LoaderUtil (getRemainingRequest, parseQuery)
import PursLoader.Options (loaderSrcOption, pscOptions)

type Effects eff = (loader :: Loader, cp :: ChildProcess | eff)

moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }

pscCommand = "psc"

(!!!) = flip (!!)

loader' :: forall eff. LoaderRef -> String -> Aff (Effects eff) (Maybe String)
loader' ref source = do
  liftEff $ cacheable ref

  let request = getRemainingRequest ref
      parsed = parseQuery $ query ref
      srcs = fromMaybe [] (loaderSrcOption parsed)
      opts = pscOptions parsed
      moduleName = match moduleRegex source >>= (!!!) 1
      result = (\a -> "module.exports = require('" ++ a ++ "');") <$> moduleName

  spawn pscCommand (srcs <> opts)
  return result

loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit
loader ref source = do
  callback <- async ref
  runAff (\e -> callback (Just e) "")
         (maybe (callback (Just (error "Loader has failed to run")) "")
                (callback Nothing))
         (loader' ref source)

loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit)
loaderFn = mkFn2 loader