Install with [npm](https://npmjs.org/package/purs-loader).
```
-// For PureScript 0.9 and newer
+// For PureScript 0.11 and newer
npm install purs-loader --save-dev
+// For PureScript 0.9 and 0.10
+npm install purs-loader@purescript-0.9 --save-dev
+
// For PureScript 0.8
npm install purs-loader@purescript-0.8 --save-dev
```
+++ /dev/null
-'use strict';
-
-const path = require('path');
-
-const Promise = require('bluebird')
-
-const fs = Promise.promisifyAll(require('fs'))
-
-const spawn = require('cross-spawn')
-
-const debug = require('debug')('purs-loader');
-
-const dargs = require('./dargs');
-
-function compile(psModule) {
- const options = psModule.options
- const cache = psModule.cache
- const stderr = []
-
- if (cache.compilationStarted) return Promise.resolve(psModule)
-
- cache.compilationStarted = true
-
- const args = dargs(Object.assign({
- _: options.src,
- output: options.output,
- }, options.pscArgs))
-
- debug('spawning compiler %s %o', options.psc, args)
-
- return (new Promise((resolve, reject) => {
- debug('compiling PureScript...')
-
- const compilation = spawn(options.psc, args)
-
- compilation.stderr.on('data', data => {
- stderr.push(data.toString());
- });
-
- compilation.on('close', code => {
- debug('finished compiling PureScript.')
- cache.compilationFinished = true
- if (code !== 0) {
- const errorMessage = stderr.join('');
- if (errorMessage.length) {
- psModule.emitError(errorMessage);
- }
- if (options.watch) {
- resolve(psModule);
- }
- else {
- reject(new Error('compilation failed'))
- }
- } else {
- const warningMessage = stderr.join('');
- if (options.warnings && warningMessage.length) {
- psModule.emitWarning(warningMessage);
- }
- resolve(psModule)
- }
- })
- }))
- .then(compilerOutput => {
- if (options.bundle) {
- return bundle(options, cache).then(() => psModule)
- }
- return psModule
- })
-}
-module.exports.compile = compile;
-
-function bundle(options, cache) {
- if (cache.bundle) return Promise.resolve(cache.bundle)
-
- const stdout = []
- const stderr = cache.bundle = []
-
- const args = dargs(Object.assign({
- _: [path.join(options.output, '*', '*.js')],
- output: options.bundleOutput,
- namespace: options.bundleNamespace,
- }, options.pscBundleArgs))
-
- cache.bundleModules.forEach(name => args.push('--module', name))
-
- debug('spawning bundler %s %o', options.pscBundle, args.join(' '))
-
- return (new Promise((resolve, reject) => {
- debug('bundling PureScript...')
-
- const compilation = spawn(options.pscBundle, args)
-
- compilation.stdout.on('data', data => stdout.push(data.toString()))
- compilation.stderr.on('data', data => stderr.push(data.toString()))
- compilation.on('close', code => {
- debug('finished bundling PureScript.')
- if (code !== 0) {
- const errorMessage = stderr.join('');
- if (errorMessage.length) {
- psModule.emitError(errorMessage);
- }
- return reject(new Error('bundling failed'))
- }
- cache.bundle = stderr
- resolve(fs.appendFileAsync(options.bundleOutput, `module.exports = ${options.bundleNamespace}`))
- })
- }))
-}
--- /dev/null
+'use strict';
+
+const path = require('path');
+
+const Promise = require('bluebird')
+
+const fs = Promise.promisifyAll(require('fs'))
+
+const spawn = require('cross-spawn')
+
+const debug = require('debug')('purs-loader');
+
+const dargs = require('./dargs');
+
+module.exports = function bundle(options, cache) {
+ if (cache.bundle) return Promise.resolve(cache.bundle)
+
+ const stdout = []
+
+ const stderr = cache.bundle = []
+
+ const bundleCommand = options.pscBundle || 'purs';
+
+ const bundleArgs = (options.pscBundle ? [] : [ 'bundle' ]).concat(dargs(Object.assign({
+ _: [path.join(options.output, '*', '*.js')],
+ output: options.bundleOutput,
+ namespace: options.bundleNamespace,
+ }, options.pscBundleArgs)));
+
+ cache.bundleModules.forEach(name => bundleArgs.push('--module', name))
+
+ debug('spawning bundler %s %o', bundleCommand, bundleArgs);
+
+ return (new Promise((resolve, reject) => {
+ debug('bundling PureScript...')
+
+ const compilation = spawn(bundleCommand, bundleArgs)
+
+ compilation.stdout.on('data', data => stdout.push(data.toString()))
+
+ compilation.stderr.on('data', data => stderr.push(data.toString()))
+
+ compilation.on('close', code => {
+ debug('finished bundling PureScript.')
+
+ if (code !== 0) {
+ const errorMessage = stderr.join('');
+ if (errorMessage.length) {
+ psModule.emitError(errorMessage);
+ }
+ return reject(new Error('bundling failed'))
+ }
+
+ cache.bundle = stderr
+
+ resolve(fs.appendFileAsync(options.bundleOutput, `module.exports = ${options.bundleNamespace}`))
+ })
+ }))
+};
--- /dev/null
+'use strict';
+
+const Promise = require('bluebird');
+
+const spawn = require('cross-spawn');
+
+const debug = require('debug')('purs-loader');
+
+const dargs = require('./dargs');
+
+module.exports = function compile(psModule) {
+ const options = psModule.options
+
+ const cache = psModule.cache
+
+ const stderr = []
+
+ const compileCommand = options.psc || 'purs';
+
+ const compileArgs = (options.psc ? [] : [ 'compile' ]).concat(dargs(Object.assign({
+ _: options.src,
+ output: options.output,
+ }, options.pscArgs)))
+
+ debug('spawning compiler %s %o', compileCommand, compileArgs)
+
+ return new Promise((resolve, reject) => {
+ debug('compiling PureScript...')
+
+ const compilation = spawn(compileCommand, compileArgs)
+
+ compilation.stderr.on('data', data => {
+ stderr.push(data.toString());
+ });
+
+ compilation.on('close', code => {
+ debug('finished compiling PureScript.')
+ if (code !== 0) {
+ const errorMessage = stderr.join('');
+ if (errorMessage.length) {
+ psModule.emitError(errorMessage);
+ }
+ if (options.watch) {
+ resolve(psModule);
+ }
+ else {
+ reject(new Error('compilation failed'))
+ }
+ } else {
+ const warningMessage = stderr.join('');
+ if (options.warnings && warningMessage.length) {
+ psModule.emitWarning(warningMessage);
+ }
+ resolve(psModule)
+ }
+ })
+ });
+};
const PsModuleMap = require('./PsModuleMap');
-function connect(psModule) {
+module.exports.connect = function connect(psModule) {
const options = psModule.options
const cache = psModule.cache
const connect_ = () => new Promise((resolve, reject) => {
const args = dargs(options.pscIdeArgs)
- debug('attempting to connect to psc-ide-server', args)
+ debug('attempting to run purs ide client: %o', args)
- const ideClient = spawn('psc-ide-client', args)
+ const ideClient = spawn('purs', ['ide', 'client'].concat(args))
ideClient.stderr.on('data', data => {
debug(data.toString())
cache.ideServer = false
- reject(new Error('psc-ide-client failed'))
+ reject(new Error('purs ide client failed'))
})
ideClient.stdout.once('data', data => {
debug(data.toString())
resolve(psModule)
} else {
cache.ideServer = ideServer
- reject(new Error('psc-ide-client failed'))
+ reject(new Error('purs ide client failed'))
}
} else {
cache.ideServer = false
- reject(new Error('psc-ide-client failed'))
+ reject(new Error('purs ide client failed'))
}
})
ideClient.stdin.resume()
'_': options.src
}, options.pscIdeServerArgs))
- debug('attempting to start psc-ide-server', serverArgs)
+ debug('attempting to start purs ide server: %o', serverArgs)
- const ideServer = cache.ideServer = spawn('psc-ide-server', serverArgs)
+ const ideServer = cache.ideServer = spawn('purs', ['ide', 'server'].concat(serverArgs))
ideServer.stdout.on('data', data => {
- debug('psc-ide-server stdout: %s', data.toString());
+ debug('purs ide server stdout: %s', data.toString());
});
ideServer.stderr.on('data', data => {
- debug('psc-ide-server stderr: %s', data.toString());
+ debug('purs ide server stderr: %s', data.toString());
});
ideServer.on('error', error => {
- debug('psc-ide-server error: %o', error);
+ debug('purs ide server error: %o', error);
});
ideServer.on('close', (code, signal) => {
- debug('psc-ide-server close: %s %s', code, signal);
+ debug('purs ide server close: %s %s', code, signal);
});
return retryPromise((retry, number) => {
if (!cache.ideServer && number === 9) {
debug(error)
- console.warn('Failed to connect to or start psc-ide-server. A full compilation will occur on rebuild');
+ console.warn('Failed to connect to or start purs ide server. A full compilation will occur on rebuild');
return Promise.resolve(psModule)
}
minTimeout: 333,
maxTimeout: 333,
})
-}
-module.exports.connect = connect;
+};
-function rebuild(psModule) {
+module.exports.rebuild = function rebuild(psModule) {
const options = psModule.options
const cache = psModule.cache
- debug('attempting rebuild with psc-ide-client %s', psModule.srcPath)
+ debug('attempting rebuild with purs ide client %s', psModule.srcPath)
const request = (body) => new Promise((resolve, reject) => {
const args = dargs(options.pscIdeArgs)
- const ideClient = spawn('psc-ide-client', args)
+ const ideClient = spawn('purs', ['ide', 'client'].concat(args))
var stdout = ''
var stderr = ''
ideClient.on('close', code => {
if (code !== 0) {
- const error = stderr === '' ? 'Failed to spawn psc-ide-client' : stderr
+ const error = stderr === '' ? 'Failed to spawn purs ide client' : stderr
return reject(new Error(error))
}
})
})
- debug('psc-ide-client stdin: %o', body);
+ debug('purs ide client stdin: %o', body);
ideClient.stdin.write(JSON.stringify(body))
ideClient.stdin.write('\n')
file: psModule.srcPath,
}
})
-}
-module.exports.rebuild = rebuild;
+};
function formatIdeResult(result, options, index, length) {
let numAndErr = `[${index+1}/${length} ${result.errorCode}]`
'use strict'
const debug = require('debug')('purs-loader')
+
const loaderUtils = require('loader-utils')
+
const Promise = require('bluebird')
+
const path = require('path')
-const PsModuleMap = require('./PsModuleMap');
-const Psc = require('./Psc');
-const PscIde = require('./PscIde');
+
+const PsModuleMap = require('./purs-module-map');
+
+const compile = require('./compile');
+
+const bundle = require('./bundle');
+
+const ide = require('./ide');
+
const toJavaScript = require('./to-javascript');
+
const dargs = require('./dargs');
+
const spawn = require('cross-spawn').sync
+
const eol = require('os').EOL
module.exports = function purescriptLoader(source, map) {
const defaultDeps = depsPaths(options.pscPackage)
const defaultOptions = {
context: config.context,
- psc: 'psc',
+ psc: null,
pscArgs: {},
- pscBundle: 'psc-bundle',
+ pscBundle: null,
pscBundleArgs: {},
pscIde: false,
pscIdeColors: options.psc === 'psa',
});
}
- const psModuleName = PsModuleMap.match(source)
+ const psModuleName = PsModuleMap.matchModule(source)
const psModule = {
name: psModuleName,
load: js => callback(null, js),
}
if (cache.rebuild) {
- return PscIde.connect(psModule)
- .then(PscIde.rebuild)
+ return ide.connect(psModule)
+ .then(ide.rebuild)
.then(toJavaScript)
.then(psModule.load)
.catch(psModule.reject)
cache.deferred.push(psModule)
if (!cache.compilationStarted) {
- return Psc.compile(psModule)
- .then(() => PsModuleMap.makeMap(options.src).then(map => {
- debug('rebuilt module map after compile');
- cache.psModuleMap = map;
- }))
+ cache.compilationStarted = true;
+
+ return compile(psModule)
+ .then(() => {
+ cache.compilationFinished = true;
+
+ const bundlePromise = options.bundle ? bundle(options, cache) : Promise.resolve();
+
+ return bundlePromise.then(() =>
+ PsModuleMap.makeMap(options.src).then(map => {
+ debug('rebuilt module map after compile');
+ cache.psModuleMap = map;
+ })
+ );
+ })
.then(() => Promise.map(cache.deferred, psModule => {
if (typeof cache.ideServer === 'object') cache.ideServer.kill()
return toJavaScript(psModule).then(psModule.load)
const importModuleRegex = /(?:^|\n)\s*import\s+([\w\.]+)/ig;
-function matchModule(str) {
+module.exports.matchModule = function matchModule(str) {
const matches = str.match(srcModuleRegex);
return matches && matches[1];
-}
-module.exports.match = matchModule;
+};
-function matchImports(str) {
+module.exports.matchImports = function matchImports(str) {
const matches = str.match(importModuleRegex);
return (matches || []).map(a => a.replace(/\n?\s*import\s+/i, ''));
-}
-module.exports.matchImports = matchImports;
+};
-function makeMapEntry(filePurs) {
+module.exports.makeMapEntry = function makeMapEntry(filePurs) {
const dirname = path.dirname(filePurs);
const basename = path.basename(filePurs, '.purs');
const sourceJs = fileMap.fileJs;
- const moduleName = matchModule(sourcePurs);
+ const moduleName = module.exports.matchModule(sourcePurs);
- const imports = matchImports(sourcePurs);
+ const imports = module.exports.matchImports(sourcePurs);
const map = {};
});
return result;
-}
-module.exports.makeMapEntry = makeMapEntry;
+};
-function makeMap(src) {
+module.exports.makeMap = function makeMap(src) {
debug('loading PureScript source and FFI files from %o', src);
const globs = [].concat(src);
return globby(globs).then(paths =>
- Promise.all(paths.map(makeMapEntry)).then(result =>
+ Promise.all(paths.map(module.exports.makeMapEntry)).then(result =>
result.reduce(Object.assign, {})
)
);
-}
-module.exports.makeMap = makeMap;
+};