X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=src%2Findex.js;h=bd2a35d05435268319001d8795c926acba4d697c;hb=58f78e37f04f5f64d2d6f40acf650379b9f7eab2;hp=23a99dd856dc908b56040e8ece6540054997e8d9;hpb=9dc1021066dea00eb43574e705df383728e667e2;p=github%2Ffretlink%2Fpurs-loader.git diff --git a/src/index.js b/src/index.js index 23a99dd..bd2a35d 100644 --- a/src/index.js +++ b/src/index.js @@ -10,7 +10,8 @@ const spawn = require('child_process').spawn const path = require('path') const retryPromise = require('promise-retry') -const psModuleRegex = /(?:^|\n)module\s+([\w\.]+)/i +const ffiModuleRegex = /\/\/\s+module\s+([\w\.]+)/i +const srcModuleRegex = /(?:^|\n)module\s+([\w\.]+)/i const requireRegex = /require\(['"]\.\.\/([\w\.]+)['"]\)/g module.exports = function purescriptLoader(source, map) { @@ -77,7 +78,7 @@ module.exports = function purescriptLoader(source, map) { }) } - const psModuleName = match(psModuleRegex, source) + const psModuleName = match(srcModuleRegex, source) const psModule = { name: psModuleName, load: js => callback(null, js), @@ -135,7 +136,7 @@ function toJavaScript(psModule) { return Promise.props({ js: fs.readFileAsync(jsPath, 'utf8'), - psModuleMap: psModuleMap(options.src, cache) + psModuleMap: psModuleMap(options, cache) }).then(result => { let js = '' @@ -147,15 +148,13 @@ function toJavaScript(psModule) { } else { // replace require paths to output files generated by psc with paths // to purescript sources, which are then also run through this loader. - const foreignRequire = 'require("' + path.resolve( - path.join(psModule.options.output, psModule.name, 'foreign.js') - ) + '")' - js = result.js .replace(requireRegex, (m, p1) => { - return 'require("' + result.psModuleMap[p1] + '")' + return 'require("' + result.psModuleMap[p1].src + '")' + }) + .replace(/require\(['"]\.\/foreign['"]\)/g, (m, p1) => { + return 'require("' + result.psModuleMap[psModule.name].ffi + '")' }) - .replace(/require\(['"]\.\/foreign['"]\)/g, foreignRequire) } return js @@ -217,11 +216,27 @@ function rebuild(psModule) { const args = dargs(options.pscIdeArgs) const ideClient = spawn('psc-ide-client', args) - ideClient.stdout.once('data', data => { + var stdout = '' + var stderr = '' + + ideClient.stdout.on('data', data => { + stdout = stdout + data.toString() + }) + + ideClient.stderr.on('data', data => { + stderr = stderr + data.toString() + }) + + ideClient.on('close', code => { + if (code !== 0) { + const error = stderr === '' ? 'Failed to spawn psc-ide-client' : stderr + return reject(new Error(error)) + } + let res = null try { - res = JSON.parse(data.toString()) + res = JSON.parse(stdout.toString()) debug(res) } catch (err) { return reject(err) @@ -255,8 +270,6 @@ function rebuild(psModule) { }) }) - ideClient.stderr.once('data', data => reject(data.toString())) - ideClient.stdin.write(JSON.stringify(body)) ideClient.stdin.write('\n') }) @@ -357,20 +370,30 @@ function bundle(options, cache) { } // map of PS module names to their source path -function psModuleMap(globs, cache) { +function psModuleMap(options, cache) { if (cache.psModuleMap) return Promise.resolve(cache.psModuleMap) + const globs = [].concat(options.src).concat(options.ffi) + return globby(globs).then(paths => { return Promise .props(paths.reduce((map, file) => { map[file] = fs.readFileAsync(file, 'utf8') return map }, {})) - .then(srcMap => { - cache.psModuleMap = Object.keys(srcMap).reduce((map, file) => { - const source = srcMap[file] - const psModuleName = match(psModuleRegex, source) - map[psModuleName] = path.resolve(file) + .then(fileMap => { + cache.psModuleMap = Object.keys(fileMap).reduce((map, file) => { + const source = fileMap[file] + const ext = path.extname(file) + const isPurs = ext.match(/purs$/i) + const moduleRegex = isPurs ? srcModuleRegex : ffiModuleRegex + const moduleName = match(moduleRegex, source) + map[moduleName] = map[moduleName] || {} + if (isPurs) { + map[moduleName].src = path.resolve(file) + } else { + map[moduleName].ffi = path.resolve(file) + } return map }, {}) return cache.psModuleMap @@ -467,6 +490,6 @@ function dargs(obj) { else if (Array.isArray(val)) val.forEach(v => args.push(arg, v)) else args.push(arg, obj[key]) - return args + return args.filter(arg => (typeof arg !== 'boolean')) }, []) }