+'use strict';
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var debug_ = require('debug');
+
+var debug = debug_('purs-loader');
+
+var debugVerbose = debug_('purs-loader:verbose');
+
+var loaderUtils = require('loader-utils');
+
+var Promise = require('bluebird');
+
+var path = require('path');
+
+var PsModuleMap = require('./purs-module-map');
+
+var compile = require('./compile');
+
+var bundle = require('./bundle');
+
+var ide = require('./ide');
+
+var toJavaScript = require('./to-javascript');
+
+var sourceMaps = require('./source-maps');
+
+var dargs = require('./dargs');
+
+var utils = require('./utils');
+
+var spawn = require('cross-spawn').sync;
+
+var eol = require('os').EOL;
+
+var CACHE_VAR = {
+ rebuild: false,
+ deferred: [],
+ bundleModules: [],
+ ideServer: null,
+ psModuleMap: null,
+ warnings: [],
+ errors: [],
+ compilationStarted: false,
+ compilationFinished: false,
+ compilationFailed: false,
+ installed: false,
+ srcOption: []
+};
+
+module.exports = function purescriptLoader(source, map) {
+ var _this = this;
+
+ this.cacheable && this.cacheable();
+
+ var webpackContext = this.options && this.options.context || this.rootContext;
+
+ var callback = this.async();
+
+ var loaderOptions = loaderUtils.getOptions(this) || {};
+
+ var srcOption = function (pscPackage) {
+ var srcPath = path.join('src', '**', '*.purs');
+
+ var bowerPath = path.join('bower_components', 'purescript-*', 'src', '**', '*.purs');
+
+ if (CACHE_VAR.srcOption.length > 0) {
+ return CACHE_VAR.srcOption;
+ } else if (pscPackage) {
+ var pscPackageCommand = 'psc-package';
+
+ var pscPackageArgs = ['sources'];
+
+ var loaderSrc = loaderOptions.src || [srcPath];
+
+ debug('psc-package %s %o', pscPackageCommand, pscPackageArgs);
+
+ var cmd = spawn(pscPackageCommand, pscPackageArgs);
+
+ if (cmd.error) {
+ throw new Error(cmd.error);
+ } else if (cmd.status !== 0) {
+ var error = cmd.stdout.toString();
+
+ throw new Error(error);
+ } else {
+ var result = cmd.stdout.toString().split(eol).filter(function (v) {
+ return v != '';
+ }).concat(loaderSrc);
+
+ debug('psc-package result: %o', result);
+
+ CACHE_VAR.srcOption = result;
+
+ return result;
+ }
+ } else {
+ var _result = loaderOptions.src || [bowerPath, srcPath];
+
+ CACHE_VAR.srcOption = _result;
+
+ return _result;
+ }
+ }(loaderOptions.pscPackage);
+
+ var options = Object.assign({
+ context: webpackContext,
+ psc: null,
+ pscArgs: {},
+ pscBundle: null,
+ pscBundleArgs: {},
+ pscIdeClient: null,
+ pscIdeClientArgs: {},
+ pscIdeServer: null,
+ pscIdeServerArgs: {},
+ pscIde: false,
+ pscIdeColors: loaderOptions.psc === 'psa',
+ pscPackage: false,
+ bundleOutput: 'output/bundle.js',
+ bundleNamespace: 'PS',
+ bundle: false,
+ warnings: true,
+ watch: false,
+ output: 'output',
+ src: []
+ }, loaderOptions, {
+ src: srcOption
+ });
+
+ if (!CACHE_VAR.installed) {
+ debugVerbose('installing purs-loader with options: %O', options);
+
+ CACHE_VAR.installed = true;
+
+ // invalidate loader CACHE_VAR when bundle is marked as invalid (in watch mode)
+ this._compiler.plugin('invalid', function () {
+ debugVerbose('invalidating loader CACHE_VAR');
+
+ CACHE_VAR = {
+ rebuild: options.pscIde,
+ deferred: [],
+ bundleModules: [],
+ ideServer: CACHE_VAR.ideServer,
+ psModuleMap: CACHE_VAR.psModuleMap,
+ warnings: [],
+ errors: [],
+ compilationStarted: false,
+ compilationFinished: false,
+ compilationFailed: false,
+ installed: CACHE_VAR.installed,
+ srcOption: []
+ };
+ });
+
+ // add psc warnings to webpack compilation warnings
+ this._compiler.plugin('after-compile', function (compilation, callback) {
+ CACHE_VAR.warnings.forEach(function (warning) {
+ compilation.warnings.push(warning);
+ });
+
+ CACHE_VAR.errors.forEach(function (error) {
+ compilation.errors.push(error);
+ });
+
+ callback();
+ });
+ }
+
+ var psModuleName = PsModuleMap.matchModule(source);
+
+ var psModule = {
+ name: psModuleName,
+ source: source,
+ load: function load(_ref) {
+ var js = _ref.js,
+ map = _ref.map;
+ return callback(null, js, map);
+ },
+ reject: function reject(error) {
+ return callback(error);
+ },
+ srcPath: this.resourcePath,
+ remainingRequest: loaderUtils.getRemainingRequest(this),
+ srcDir: path.dirname(this.resourcePath),
+ jsPath: path.resolve(path.join(options.output, psModuleName, 'index.js')),
+ options: options,
+ cache: CACHE_VAR,
+ emitWarning: function emitWarning(warning) {
+ if (options.warnings && warning.length) {
+ CACHE_VAR.warnings.push(warning);
+ }
+ },
+ emitError: function emitError(pscMessage) {
+ if (pscMessage.length) {
+ var modules = [];
+
+ var matchErrorsSeparator = /\n(?=Error)/;
+ var errors = pscMessage.split(matchErrorsSeparator);
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = errors[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var error = _step.value;
+
+ var matchErrLocation = /at (.+\.purs) line (\d+), column (\d+) - line (\d+), column (\d+)/;
+
+ var _ref2 = matchErrLocation.exec(error) || [],
+ _ref3 = _slicedToArray(_ref2, 2),
+ filename = _ref3[1];
+
+ if (!filename) continue;
+
+ var baseModulePath = path.join(_this.rootContext, filename);
+ _this.addDependency(baseModulePath);
+
+ var matchErrModuleName = /in module ((?:\w+\.)*\w+)/;
+
+ var _ref4 = matchErrModuleName.exec(error) || [],
+ _ref5 = _slicedToArray(_ref4, 2),
+ baseModuleName = _ref5[1];
+
+ if (!baseModuleName) continue;
+
+ var matchMissingModuleName = /Module ((?:\w+\.)*\w+) was not found/;
+ var matchMissingImportFromModuleName = /Cannot import value \w+ from module ((?:\w+\.)*\w+)/;
+ var _arr = [matchMissingModuleName, matchMissingImportFromModuleName];
+ for (var _i = 0; _i < _arr.length; _i++) {
+ var re = _arr[_i];
+ var _ref6 = re.exec(error) || [],
+ _ref7 = _slicedToArray(_ref6, 2),
+ targetModuleName = _ref7[1];
+
+ if (targetModuleName) {
+ var resolved = utils.resolvePursModule({
+ baseModulePath: baseModulePath,
+ baseModuleName: baseModuleName,
+ targetModuleName: targetModuleName
+ });
+ _this.addDependency(resolved);
+ }
+ }
+
+ var desc = {
+ name: baseModuleName,
+ filename: baseModulePath
+ };
+
+ if (typeof _this.describePscError === 'function') {
+ var _describePscError = _this.describePscError(error, desc),
+ _describePscError$dep = _describePscError.dependencies,
+ dependencies = _describePscError$dep === undefined ? [] : _describePscError$dep,
+ details = _describePscError.details;
+
+ var _iteratorNormalCompletion2 = true;
+ var _didIteratorError2 = false;
+ var _iteratorError2 = undefined;
+
+ try {
+
+ for (var _iterator2 = dependencies[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
+ var dep = _step2.value;
+
+ _this.addDependency(dep);
+ }
+ } catch (err) {
+ _didIteratorError2 = true;
+ _iteratorError2 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion2 && _iterator2.return) {
+ _iterator2.return();
+ }
+ } finally {
+ if (_didIteratorError2) {
+ throw _iteratorError2;
+ }
+ }
+ }
+
+ Object.assign(desc, details);
+ }
+
+ modules.push(desc);
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator.return) {
+ _iterator.return();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ CACHE_VAR.errors.push(new utils.PscError(pscMessage, modules));
+ }
+ }
+ };
+
+ debug('loading %s', psModule.name);
+
+ if (options.bundle) {
+ CACHE_VAR.bundleModules.push(psModule.name);
+ }
+
+ if (CACHE_VAR.rebuild) {
+ var connect = function connect() {
+ if (!CACHE_VAR.ideServer) {
+ CACHE_VAR.ideServer = true;
+
+ return ide.connect(psModule).then(function (ideServer) {
+ CACHE_VAR.ideServer = ideServer;
+ return psModule;
+ }).then(ide.loadWithRetry).catch(function (error) {
+ if (CACHE_VAR.ideServer.kill) {
+ debug('ide failed to initially load modules, stopping the ide server process');
+
+ CACHE_VAR.ideServer.kill();
+ }
+
+ CACHE_VAR.ideServer = null;
+
+ return Promise.reject(error);
+ });
+ } else {
+ return Promise.resolve(psModule);
+ }
+ };
+
+ var rebuild = function rebuild() {
+ return ide.rebuild(psModule).then(function () {
+ return toJavaScript(psModule).then(function (js) {
+ return sourceMaps(psModule, js);
+ }).then(psModule.load).catch(psModule.reject);
+ }).catch(function (error) {
+ if (error instanceof ide.UnknownModuleError) {
+ // Store the modules that trigger a recompile due to an
+ // unknown module error. We need to wait until compilation is
+ // done before loading these files.
+
+ CACHE_VAR.deferred.push(psModule);
+
+ if (!CACHE_VAR.compilationStarted) {
+ CACHE_VAR.compilationStarted = true;
+
+ return compile(psModule).then(function () {
+ CACHE_VAR.compilationFinished = true;
+ }).then(function () {
+ return Promise.map(CACHE_VAR.deferred, function (psModule) {
+ return ide.load(psModule).then(function () {
+ return toJavaScript(psModule);
+ }).then(function (js) {
+ return sourceMaps(psModule, js);
+ }).then(psModule.load);
+ });
+ }).catch(function (error) {
+ CACHE_VAR.compilationFailed = true;
+
+ CACHE_VAR.deferred[0].reject(error);
+
+ CACHE_VAR.deferred.slice(1).forEach(function (psModule) {
+ psModule.reject(new Error('purs-loader failed'));
+ });
+ });
+ } else if (CACHE_VAR.compilationFailed) {
+ CACHE_VAR.deferred.pop().reject(new Error('purs-loader failed'));
+ } else {
+ // The compilation has started. We must wait until it is
+ // done in order to ensure the module map contains all of
+ // the unknown modules.
+ }
+ } else {
+ debug('ide rebuild failed due to an unhandled error: %o', error);
+
+ psModule.reject(error);
+ }
+ });
+ };
+
+ connect().then(rebuild);
+ } else if (CACHE_VAR.compilationFinished) {
+ debugVerbose('compilation is already finished, loading module %s', psModule.name);
+
+ toJavaScript(psModule).then(function (js) {
+ return sourceMaps(psModule, js);
+ }).then(psModule.load).catch(psModule.reject);
+ } else {
+ // The compilation has not finished yet. We need to wait for
+ // compilation to finish before the loaders run so that references
+ // to compiled output are valid. Push the modules into the CACHE_VAR to
+ // be loaded once the complation is complete.
+
+ CACHE_VAR.deferred.push(psModule);
+
+ if (!CACHE_VAR.compilationStarted) {
+ CACHE_VAR.compilationStarted = true;
+
+ compile(psModule).then(function () {
+ CACHE_VAR.compilationFinished = true;
+ }).then(function () {
+ if (options.bundle) {
+ return bundle(options, CACHE_VAR.bundleModules);
+ }
+ }).then(function () {
+ return Promise.map(CACHE_VAR.deferred, function (psModule) {
+ return toJavaScript(psModule).then(function (js) {
+ return sourceMaps(psModule, js);
+ }).then(psModule.load);
+ });
+ }).catch(function (error) {
+ CACHE_VAR.compilationFailed = true;
+
+ CACHE_VAR.deferred[0].reject(error);
+
+ CACHE_VAR.deferred.slice(1).forEach(function (psModule) {
+ psModule.reject(new Error('purs-loader failed'));
+ });
+ });
+ } else if (CACHE_VAR.compilationFailed) {
+ CACHE_VAR.deferred.pop().reject(new Error('purs-loader failed'));
+ } else {
+ // The complation has started. Nothing to do but wait until it is
+ // done before loading all of the modules.
+ }
+ }
+};
\ No newline at end of file