diff options
author | Alex Mingoia <talk@alexmingoia.com> | 2016-05-10 00:09:28 -0700 |
---|---|---|
committer | Alex Mingoia <talk@alexmingoia.com> | 2016-05-10 00:09:28 -0700 |
commit | 7de41f10b4ff0f0d6b45d59bee0f166c3cfe3f9f (patch) | |
tree | 9ee160ba5b7dab900ccd1cfa657760e4103a175e /src/PursLoader | |
parent | 777472b3830cb3d2ff3390003ea422c6d4522715 (diff) | |
download | purs-loader-7de41f10b4ff0f0d6b45d59bee0f166c3cfe3f9f.tar.gz purs-loader-7de41f10b4ff0f0d6b45d59bee0f166c3cfe3f9f.tar.zst purs-loader-7de41f10b4ff0f0d6b45d59bee0f166c3cfe3f9f.zip |
Refactor to compile independently of purescript-webpack-plugin.
- Remove dependence on purescript-webpack-plugin
- Fixes double-compilation issue by loading compiled JS instead of adding
dependency.
- Uses `psc-ide-server` for fast rebuilds.
Diffstat (limited to 'src/PursLoader')
-rw-r--r-- | src/PursLoader/Debug.js | 12 | ||||
-rw-r--r-- | src/PursLoader/Debug.purs | 9 | ||||
-rw-r--r-- | src/PursLoader/JsStringEscape.js | 7 | ||||
-rw-r--r-- | src/PursLoader/JsStringEscape.purs | 3 | ||||
-rw-r--r-- | src/PursLoader/Loader.purs | 108 | ||||
-rw-r--r-- | src/PursLoader/LoaderRef.js | 50 | ||||
-rw-r--r-- | src/PursLoader/LoaderRef.purs | 40 | ||||
-rw-r--r-- | src/PursLoader/Path.js | 24 | ||||
-rw-r--r-- | src/PursLoader/Path.purs | 14 | ||||
-rw-r--r-- | src/PursLoader/Plugin.js | 14 | ||||
-rw-r--r-- | src/PursLoader/Plugin.purs | 34 |
11 files changed, 0 insertions, 315 deletions
diff --git a/src/PursLoader/Debug.js b/src/PursLoader/Debug.js deleted file mode 100644 index 85eca10..0000000 --- a/src/PursLoader/Debug.js +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | 'use strict'; | ||
2 | |||
3 | // module PursLoader.Debug | ||
4 | |||
5 | var debug_ = require('debug')('purs-loader'); | ||
6 | |||
7 | function debug(message) { | ||
8 | return function(){ | ||
9 | debug_(message); | ||
10 | }; | ||
11 | } | ||
12 | exports.debug = debug; | ||
diff --git a/src/PursLoader/Debug.purs b/src/PursLoader/Debug.purs deleted file mode 100644 index 7a02f69..0000000 --- a/src/PursLoader/Debug.purs +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | module PursLoader.Debug (debug) where | ||
2 | |||
3 | import Prelude (Unit()) | ||
4 | |||
5 | import Control.Monad.Eff (Eff()) | ||
6 | |||
7 | import PursLoader.LoaderRef (Loader()) | ||
8 | |||
9 | foreign import debug :: forall eff. String -> Eff (loader :: Loader | eff) Unit | ||
diff --git a/src/PursLoader/JsStringEscape.js b/src/PursLoader/JsStringEscape.js deleted file mode 100644 index ff0a1a6..0000000 --- a/src/PursLoader/JsStringEscape.js +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | 'use strict'; | ||
2 | |||
3 | // module PursLoader.JsStringEscape | ||
4 | |||
5 | var jsStringEscape = require('js-string-escape'); | ||
6 | |||
7 | exports.jsStringEscape = jsStringEscape; | ||
diff --git a/src/PursLoader/JsStringEscape.purs b/src/PursLoader/JsStringEscape.purs deleted file mode 100644 index 79590ae..0000000 --- a/src/PursLoader/JsStringEscape.purs +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | module PursLoader.JsStringEscape (jsStringEscape) where | ||
2 | |||
3 | foreign import jsStringEscape :: String -> String | ||
diff --git a/src/PursLoader/Loader.purs b/src/PursLoader/Loader.purs deleted file mode 100644 index acb0993..0000000 --- a/src/PursLoader/Loader.purs +++ /dev/null | |||
@@ -1,108 +0,0 @@ | |||
1 | module PursLoader.Loader | ||
2 | ( Effects() | ||
3 | , Effects_() | ||
4 | , loader | ||
5 | , loaderFn | ||
6 | ) where | ||
7 | |||
8 | import Prelude (Unit(), ($), (>>=), (<$>), (<*>), (++), (<<<), bind, const, id, pure, unit) | ||
9 | |||
10 | import Control.Bind (join) | ||
11 | import Control.Monad.Eff (Eff(), foreachE) | ||
12 | import Control.Monad.Eff.Console (CONSOLE()) | ||
13 | import Control.Monad.Eff.Exception (EXCEPTION(), Error(), error) | ||
14 | |||
15 | import Data.Array ((!!)) | ||
16 | import Data.Either (Either(..), either) | ||
17 | import Data.Function (Fn2(), mkFn2) | ||
18 | import Data.Maybe (maybe) | ||
19 | import Data.Nullable (toMaybe) | ||
20 | import Data.String.Regex (Regex(), match, noFlags, regex) | ||
21 | |||
22 | import Unsafe.Coerce (unsafeCoerce) | ||
23 | |||
24 | import PursLoader.Debug (debug) | ||
25 | import PursLoader.JsStringEscape (jsStringEscape) | ||
26 | import PursLoader.LoaderRef | ||
27 | ( AsyncCallback() | ||
28 | , LoaderRef() | ||
29 | , Loader() | ||
30 | , async | ||
31 | , cacheable | ||
32 | , addDependency | ||
33 | , resourcePath | ||
34 | ) | ||
35 | import PursLoader.Path (dirname, joinPath, relative) | ||
36 | import PursLoader.Plugin as Plugin | ||
37 | |||
38 | type Effects eff = (console :: CONSOLE, err :: EXCEPTION | eff) | ||
39 | |||
40 | type Effects_ eff = Effects (loader :: Loader | eff) | ||
41 | |||
42 | loader :: forall eff. LoaderRef -> String -> Eff (Effects_ eff) Unit | ||
43 | loader ref source = do | ||
44 | callback <- async ref | ||
45 | |||
46 | cacheable ref | ||
47 | |||
48 | debug "Invoke PureScript plugin compilation" | ||
49 | |||
50 | pluginContext.compile (compile callback) | ||
51 | where | ||
52 | pluginContext :: Plugin.Context (Effects_ eff) | ||
53 | pluginContext = (unsafeCoerce ref).purescriptWebpackPluginContext | ||
54 | |||
55 | compile :: AsyncCallback (Effects eff) -> Plugin.Compile (Effects_ eff) | ||
56 | compile callback error' graph = do | ||
57 | either (const $ pure unit) (\a -> debug ("Adding PureScript dependency " ++ a)) name | ||
58 | |||
59 | addDependency ref (resourcePath ref) | ||
60 | |||
61 | either (const $ callback (pure fixedError) "") id | ||
62 | (handle <$> name <*> dependencies <*> exports) | ||
63 | where | ||
64 | fixedError :: Error | ||
65 | fixedError = error "PureScript compilation has failed." | ||
66 | |||
67 | handle :: String -> Array String -> String -> Eff (Effects_ eff) Unit | ||
68 | handle name' deps res = do | ||
69 | debug ("Adding PureScript dependencies for " ++ name') | ||
70 | foreachE deps (addDependency ref) | ||
71 | debug "Generated loader result" | ||
72 | debug res | ||
73 | callback (const fixedError <$> toMaybe error') res | ||
74 | |||
75 | exports :: Either Error String | ||
76 | exports = | ||
77 | if pluginContext.options.bundle | ||
78 | then bundleExport <$> name | ||
79 | else moduleExport <<< modulePath <$> name | ||
80 | where | ||
81 | bundleExport :: String -> String | ||
82 | bundleExport name' = "module.exports = require('" ++ jsStringEscape path ++ "')['" ++ name' ++ "'];" | ||
83 | where | ||
84 | path :: String | ||
85 | path = relative resourceDir pluginContext.options.bundleOutput | ||
86 | |||
87 | moduleExport :: String -> String | ||
88 | moduleExport path = "module.exports = require('" ++ jsStringEscape path ++ "');" | ||
89 | |||
90 | modulePath :: String -> String | ||
91 | modulePath = relative resourceDir <<< joinPath pluginContext.options.output | ||
92 | |||
93 | resourceDir :: String | ||
94 | resourceDir = dirname (resourcePath ref) | ||
95 | |||
96 | dependencies :: Either Error (Array String) | ||
97 | dependencies = Plugin.dependenciesOf graph (resourcePath ref) | ||
98 | |||
99 | name :: Either Error String | ||
100 | name = | ||
101 | maybe (Left $ error "Failed to parse module name") Right | ||
102 | (join $ match re source >>= \as -> as !! 1) | ||
103 | where | ||
104 | re :: Regex | ||
105 | re = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true } | ||
106 | |||
107 | loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects_ eff) Unit) | ||
108 | loaderFn = mkFn2 loader | ||
diff --git a/src/PursLoader/LoaderRef.js b/src/PursLoader/LoaderRef.js deleted file mode 100644 index a5d8e1f..0000000 --- a/src/PursLoader/LoaderRef.js +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | 'use strict'; | ||
2 | |||
3 | // module PursLoader.LoaderRef | ||
4 | |||
5 | function asyncFn(isJust, fromMaybe, ref){ | ||
6 | return function(){ | ||
7 | var callback = ref.async(); | ||
8 | return function(error){ | ||
9 | return function(value){ | ||
10 | return function(){ | ||
11 | return isJust(error) ? callback(fromMaybe(new Error())(error)) | ||
12 | : callback(null, value); | ||
13 | }; | ||
14 | }; | ||
15 | }; | ||
16 | }; | ||
17 | } | ||
18 | function cacheable(ref){ | ||
19 | return function(){ | ||
20 | return ref.cacheable && ref.cacheable(); | ||
21 | }; | ||
22 | } | ||
23 | |||
24 | function clearDependencies(ref){ | ||
25 | return function(){ | ||
26 | return ref.clearDependencies(); | ||
27 | }; | ||
28 | } | ||
29 | |||
30 | function resourcePath(ref){ | ||
31 | return ref.resourcePath; | ||
32 | } | ||
33 | |||
34 | function addDependency(ref){ | ||
35 | return function(dep){ | ||
36 | return function(){ | ||
37 | return ref.addDependency(dep); | ||
38 | }; | ||
39 | }; | ||
40 | } | ||
41 | |||
42 | exports.asyncFn = asyncFn; | ||
43 | |||
44 | exports.cacheable = cacheable; | ||
45 | |||
46 | exports.clearDependencies = clearDependencies; | ||
47 | |||
48 | exports.resourcePath = resourcePath; | ||
49 | |||
50 | exports.addDependency = addDependency; | ||
diff --git a/src/PursLoader/LoaderRef.purs b/src/PursLoader/LoaderRef.purs deleted file mode 100644 index 140d94a..0000000 --- a/src/PursLoader/LoaderRef.purs +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | module PursLoader.LoaderRef | ||
2 | ( LoaderRef() | ||
3 | , Loader() | ||
4 | , AsyncCallback() | ||
5 | , async | ||
6 | , cacheable | ||
7 | , clearDependencies | ||
8 | , addDependency | ||
9 | , resourcePath | ||
10 | ) where | ||
11 | |||
12 | import Prelude (Unit()) | ||
13 | |||
14 | import Control.Monad.Eff (Eff()) | ||
15 | import Control.Monad.Eff.Exception (Error()) | ||
16 | |||
17 | import Data.Function (Fn3(), runFn3) | ||
18 | import Data.Maybe (Maybe(), fromMaybe, isJust) | ||
19 | |||
20 | type AsyncCallback eff = Maybe Error -> String -> Eff (loader :: Loader | eff) Unit | ||
21 | |||
22 | data LoaderRef | ||
23 | |||
24 | foreign import data Loader :: ! | ||
25 | |||
26 | foreign import asyncFn :: forall eff. Fn3 (Maybe Error -> Boolean) | ||
27 | (Error -> Maybe Error -> Error) | ||
28 | LoaderRef | ||
29 | (Eff (loader :: Loader | eff) (AsyncCallback eff)) | ||
30 | |||
31 | async :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) (Maybe Error -> String -> Eff (loader :: Loader | eff) Unit) | ||
32 | async ref = runFn3 asyncFn isJust fromMaybe ref | ||
33 | |||
34 | foreign import cacheable :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit | ||
35 | |||
36 | foreign import clearDependencies :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit | ||
37 | |||
38 | foreign import resourcePath :: LoaderRef -> String | ||
39 | |||
40 | foreign import addDependency :: forall eff. LoaderRef -> String -> Eff (loader :: Loader | eff) Unit | ||
diff --git a/src/PursLoader/Path.js b/src/PursLoader/Path.js deleted file mode 100644 index 878f256..0000000 --- a/src/PursLoader/Path.js +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | 'use strict' | ||
2 | |||
3 | // module PursLoader.Path | ||
4 | |||
5 | var path = require('path'); | ||
6 | |||
7 | function relative(from) { | ||
8 | return function(to){ | ||
9 | return path.relative(from, to); | ||
10 | }; | ||
11 | } | ||
12 | exports.relative = relative; | ||
13 | |||
14 | |||
15 | function joinPath(a) { | ||
16 | return function(b) { | ||
17 | return path.join(a, b); | ||
18 | }; | ||
19 | } | ||
20 | exports.joinPath = joinPath; | ||
21 | |||
22 | exports.resolve = path.resolve; | ||
23 | |||
24 | exports.dirname = path.dirname; | ||
diff --git a/src/PursLoader/Path.purs b/src/PursLoader/Path.purs deleted file mode 100644 index 98cad5a..0000000 --- a/src/PursLoader/Path.purs +++ /dev/null | |||
@@ -1,14 +0,0 @@ | |||
1 | module PursLoader.Path | ||
2 | ( relative | ||
3 | , resolve | ||
4 | , dirname | ||
5 | , joinPath | ||
6 | ) where | ||
7 | |||
8 | foreign import relative :: String -> String -> String | ||
9 | |||
10 | foreign import resolve :: String -> String | ||
11 | |||
12 | foreign import dirname :: String -> String | ||
13 | |||
14 | foreign import joinPath :: String -> String -> String | ||
diff --git a/src/PursLoader/Plugin.js b/src/PursLoader/Plugin.js deleted file mode 100644 index ded6df5..0000000 --- a/src/PursLoader/Plugin.js +++ /dev/null | |||
@@ -1,14 +0,0 @@ | |||
1 | 'use strict'; | ||
2 | |||
3 | // module PursLoader.Plugin | ||
4 | |||
5 | function dependenciesOfFn(left, right, graph, node) { | ||
6 | try { | ||
7 | var dependencies = graph.dependenciesOf(node); | ||
8 | return right(dependencies); | ||
9 | } | ||
10 | catch (error) { | ||
11 | return left(error); | ||
12 | } | ||
13 | } | ||
14 | exports.dependenciesOfFn = dependenciesOfFn; | ||
diff --git a/src/PursLoader/Plugin.purs b/src/PursLoader/Plugin.purs deleted file mode 100644 index c798c83..0000000 --- a/src/PursLoader/Plugin.purs +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | module PursLoader.Plugin | ||
2 | ( Compile() | ||
3 | , Context() | ||
4 | , Options() | ||
5 | , DependencyGraph() | ||
6 | , dependenciesOf | ||
7 | ) where | ||
8 | |||
9 | import Prelude (Unit()) | ||
10 | |||
11 | import Control.Monad.Eff (Eff()) | ||
12 | import Control.Monad.Eff.Exception (Error()) | ||
13 | |||
14 | import Data.Either (Either(..)) | ||
15 | import Data.Function (Fn4(), runFn4) | ||
16 | import Data.Nullable (Nullable()) | ||
17 | |||
18 | type Compile eff = Nullable Error -> DependencyGraph -> Eff eff Unit | ||
19 | |||
20 | type Context eff = { compile :: Compile eff -> Eff eff Unit, options :: Options } | ||
21 | |||
22 | type Options = { bundle :: Boolean, output :: String, bundleOutput :: String } | ||
23 | |||
24 | dependenciesOf :: DependencyGraph -> String -> Either Error (Array String) | ||
25 | dependenciesOf = runFn4 dependenciesOfFn Left Right | ||
26 | |||
27 | foreign import data DependencyGraph :: * | ||
28 | |||
29 | foreign import dependenciesOfFn | ||
30 | :: Fn4 (Error -> Either Error (Array String)) | ||
31 | (Array String -> Either Error (Array String)) | ||
32 | DependencyGraph | ||
33 | String | ||
34 | (Either Error (Array String)) | ||