diff --git a/js/embark.js b/js/embark.js deleted file mode 100644 index 74ff3ec9d..000000000 --- a/js/embark.js +++ /dev/null @@ -1,437 +0,0 @@ -import {detectSeries} from 'async'; - -var EmbarkJS = { - onReady: function (cb) { - if (typeof (__embarkContext) === 'undefined') { - return cb(); - } - return __embarkContext.execWhenReady(cb); - } -}; - -EmbarkJS.isNewWeb3 = function (web3Obj) { - var _web3 = web3Obj || (new Web3()); - if (typeof(_web3.version) === "string") { - return true; - } - return parseInt(_web3.version.api.split('.')[0], 10) >= 1; -}; - -EmbarkJS.Contract = function (options) { - var self = this; - var i, abiElement; - var ContractClass; - - this.abi = options.abi; - this.address = options.address; - this.gas = options.gas; - this.code = '0x' + options.code; - //this.web3 = options.web3 || web3; - this.web3 = options.web3; - if (!this.web3 && typeof (web3) !== 'undefined') { - this.web3 = web3; - } else if (!this.web3) { - this.web3 = window.web3; - } - - if (EmbarkJS.isNewWeb3(this.web3)) { - ContractClass = new this.web3.eth.Contract(this.abi, this.address); - ContractClass.setProvider(this.web3.currentProvider); - ContractClass.options.data = this.code; - ContractClass.options.from = this.from || this.web3.eth.defaultAccount; - ContractClass.abi = ContractClass.options.abi; - ContractClass.address = this.address; - ContractClass.gas = this.gas; - - let originalMethods = Object.keys(ContractClass); - - ContractClass._jsonInterface.forEach((abi) => { - if (originalMethods.indexOf(abi.name) >= 0) { - console.log(abi.name + " is a reserved word and cannot be used as a contract method, property or event"); - return; - } - - if (!abi.inputs) { - return; - } - - let numExpectedInputs = abi.inputs.length; - - if (abi.type === 'function' && abi.constant) { - ContractClass[abi.name] = function () { - let options = {}, cb = null, args = Array.from(arguments || []).slice(0, numExpectedInputs); - if (typeof (arguments[numExpectedInputs]) === 'function') { - cb = arguments[numExpectedInputs]; - } else if (typeof (arguments[numExpectedInputs]) === 'object') { - options = arguments[numExpectedInputs]; - cb = arguments[numExpectedInputs + 1]; - } - - let ref = ContractClass.methods[abi.name]; - let call = ref.apply(ref, ...arguments).call; - return call.apply(call, []); - }; - } else if (abi.type === 'function') { - ContractClass[abi.name] = function () { - let options = {}, cb = null, args = Array.from(arguments || []).slice(0, numExpectedInputs); - if (typeof (arguments[numExpectedInputs]) === 'function') { - cb = arguments[numExpectedInputs]; - } else if (typeof (arguments[numExpectedInputs]) === 'object') { - options = arguments[numExpectedInputs]; - cb = arguments[numExpectedInputs + 1]; - } - - let ref = ContractClass.methods[abi.name]; - let send = ref.apply(ref, args).send; - return send.apply(send, [options, cb]); - }; - } else if (abi.type === 'event') { - ContractClass[abi.name] = function (options, cb) { - let ref = ContractClass.events[abi.name]; - return ref.apply(ref, [options, cb]); - }; - } - }); - - return ContractClass; - } else { - ContractClass = this.web3.eth.contract(this.abi); - - this.eventList = []; - - if (this.abi) { - for (i = 0; i < this.abi.length; i++) { - abiElement = this.abi[i]; - if (abiElement.type === 'event') { - this.eventList.push(abiElement.name); - } - } - } - - var messageEvents = function () { - this.cb = function () { - }; - }; - - messageEvents.prototype.then = function (cb) { - this.cb = cb; - }; - - messageEvents.prototype.error = function (err) { - return err; - }; - - this._originalContractObject = ContractClass.at(this.address); - this._methods = Object.getOwnPropertyNames(this._originalContractObject).filter(function (p) { - // TODO: check for forbidden properties - if (self.eventList.indexOf(p) >= 0) { - - self[p] = function () { - var promise = new messageEvents(); - var args = Array.prototype.slice.call(arguments); - args.push(function (err, result) { - if (err) { - promise.error(err); - } else { - promise.cb(result); - } - }); - - self._originalContractObject[p].apply(self._originalContractObject[p], args); - return promise; - }; - return true; - } else if (typeof self._originalContractObject[p] === 'function') { - self[p] = function (_args) { - var args = Array.prototype.slice.call(arguments); - var fn = self._originalContractObject[p]; - var props = self.abi.find((x) => x.name == p); - - var promise = new Promise(function (resolve, reject) { - args.push(function (err, transaction) { - promise.tx = transaction; - if (err) { - return reject(err); - } - - var getConfirmation = function () { - self.web3.eth.getTransactionReceipt(transaction, function (err, receipt) { - if (err) { - return reject(err); - } - - if (receipt !== null) { - return resolve(receipt); - } - - setTimeout(getConfirmation, 1000); - }); - }; - - if (typeof transaction !== "string" || props.constant) { - resolve(transaction); - } else { - getConfirmation(); - } - }); - - fn.apply(fn, args); - }); - - return promise; - }; - return true; - } - return false; - }); - } -}; - -EmbarkJS.Contract.prototype.deploy = function (args, _options) { - var self = this; - var contractParams; - var options = _options || {}; - - contractParams = args || []; - - contractParams.push({ - from: this.web3.eth.accounts[0], - data: this.code, - gas: options.gas || 800000 - }); - - var contractObject = this.web3.eth.contract(this.abi); - - var promise = new Promise(function (resolve, reject) { - contractParams.push(function (err, transaction) { - if (err) { - reject(err); - } else if (transaction.address !== undefined) { - resolve(new EmbarkJS.Contract({ - abi: self.abi, - code: self.code, - address: transaction.address - })); - } - }); - - // returns promise - // deploys contract - // wraps it around EmbarkJS.Contract - contractObject["new"].apply(contractObject, contractParams); - }); - - - return promise; -}; - -EmbarkJS.Contract.prototype.new = EmbarkJS.Contract.prototype.deploy; - -EmbarkJS.Contract.prototype.at = function (address) { - return new EmbarkJS.Contract({abi: this.abi, code: this.code, address: address}); -}; - -EmbarkJS.Contract.prototype.send = function (value, unit, _options) { - var options, wei; - if (typeof unit === 'object') { - options = unit; - wei = value; - } else { - options = _options || {}; - wei = this.web3.toWei(value, unit); - } - - options.to = this.address; - options.value = wei; - - this.web3.eth.sendTransaction(options); -}; - -EmbarkJS.Storage = {}; - -EmbarkJS.Storage.Providers = {}; - -EmbarkJS.Storage.saveText = function (text) { - if (!this.currentStorage) { - throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); - } - return this.currentStorage.saveText(text); -}; - -EmbarkJS.Storage.get = function (hash) { - if (!this.currentStorage) { - throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); - } - return this.currentStorage.get(hash); -}; - -EmbarkJS.Storage.uploadFile = function (inputSelector) { - if (!this.currentStorage) { - throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); - } - return this.currentStorage.uploadFile(inputSelector); -}; - -EmbarkJS.Storage.getUrl = function (hash) { - if (!this.currentStorage) { - throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); - } - return this.currentStorage.getUrl(hash); -}; - -EmbarkJS.Storage.registerProvider = function (providerName, obj) { - EmbarkJS.Storage.Providers[providerName] = obj; -}; - -EmbarkJS.Storage.setProvider = function (provider, options) { - let providerObj = this.Providers[provider]; - - if (!providerObj) { - throw new Error('Unknown storage provider'); - } - - this.currentStorage = providerObj; - - return providerObj.setProvider(options); -}; - -EmbarkJS.Storage.isAvailable = function () { - if (!this.currentStorage) { - throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); - } - return this.currentStorage.isAvailable(); -}; - -EmbarkJS.Storage.setProviders = async function (dappConnOptions) { - try { - await detectSeries(dappConnOptions, async (dappConn, callback) => { - if(dappConn === '$BZZ' || dappConn.provider === 'swarm'){ - let options = dappConn; - if(dappConn === '$BZZ') options = {"useOnlyGivenProvider": true}; - try{ - await EmbarkJS.Storage.setProvider('swarm', options); - let isAvailable = await EmbarkJS.Storage.isAvailable(); - callback(null, isAvailable); - }catch(err){ - callback(null, false); // catch errors for when bzz object not initialised but config has requested it to be used - } - } - else if(dappConn.provider === 'ipfs') { - // set the provider then check the connection, if true, use that provider, else, check next provider - try{ - await EmbarkJS.Storage.setProvider('ipfs', dappConn); - let isAvailable = await EmbarkJS.Storage.isAvailable(); - callback(null, isAvailable); - } catch(err) { - callback(null, false); // catch but keep looping by not passing err to callback - } - } - }, function(err, result){ - if(!result) throw new Error('Could not connect to a storage provider using any of the dappConnections in the storage config'); - }); - } catch (err) { - throw new Error('Failed to connect to a storage provider: ' + err.message); - } -}; - -EmbarkJS.Messages = {}; - -EmbarkJS.Messages.Providers = {}; - -EmbarkJS.Messages.registerProvider = function (providerName, obj) { - EmbarkJS.Messages.Providers[providerName] = obj; -}; - -EmbarkJS.Messages.setProvider = function (provider, options) { - let providerObj = this.Providers[provider]; - - if (!providerObj) { - throw new Error('Unknown messages provider'); - } - - this.currentMessages = providerObj; - - return providerObj.setProvider(options); -}; - -EmbarkJS.Messages.isAvailable = function () { - return this.currentMessages.isAvailable(); -}; - -EmbarkJS.Messages.sendMessage = function (options) { - if (!this.currentMessages) { - throw new Error('Messages provider not set; e.g EmbarkJS.Messages.setProvider("whisper")'); - } - return this.currentMessages.sendMessage(options); -}; - -EmbarkJS.Messages.listenTo = function (options, callback) { - if (!this.currentMessages) { - throw new Error('Messages provider not set; e.g EmbarkJS.Messages.setProvider("whisper")'); - } - return this.currentMessages.listenTo(options, callback); -}; - -EmbarkJS.Names = {}; - -EmbarkJS.Names.Providers = {}; - -EmbarkJS.Names.registerProvider = function (providerName, obj) { - EmbarkJS.Names.Providers[providerName] = obj; -}; - -EmbarkJS.Names.setProvider = function (provider, options) { - let providerObj = this.Providers[provider]; - - if (!providerObj) { - throw new Error('Unknown name system provider'); - } - - this.currentNameSystems = providerObj; - - return providerObj.setProvider(options); -}; - -// resolve resolves a name into an identifier of some kind -EmbarkJS.Names.resolve = function (name, callback) { - if (!this.currentNameSystems) { - throw new Error('Name system provider not set; e.g EmbarkJS.Names.setProvider("ens")'); - } - return this.currentNameSystems.resolve(name, callback); -}; - -// the reverse of resolve, resolves using an identifier to get to a name -EmbarkJS.Names.lookup = function (identifier, callback) { - if (!this.currentNameSystems) { - throw new Error('Name system provider not set; e.g EmbarkJS.Names.setProvider("ens")'); - } - return this.currentNameSystems.lookup(identifier, callback); -}; - -EmbarkJS.Names.isAvailable = function () { - return this.currentNameSystems.isAvailable(); -}; - -// To Implement - - -// register a name -EmbarkJS.Names.register = function(name, options) { - if (!this.currentNameSystems) { - throw new Error('Name system provider not set; e.g EmbarkJS.Names.setProvider("ens")'); - } - return this.currentNameSystems.register(name, options); -}; - -EmbarkJS.Utils = { - fromAscii: function (str) { - var _web3 = new Web3(); - return _web3.utils ? _web3.utils.fromAscii(str) : _web3.fromAscii(str); - }, - toAscii: function (str) { - var _web3 = new Web3(); - return _web3.utils.toAscii(str); - } -}; - -export default EmbarkJS; diff --git a/js/embark_node.js b/js/embark_node.js deleted file mode 100644 index d7b4a92f2..000000000 --- a/js/embark_node.js +++ /dev/null @@ -1,395 +0,0 @@ -var EmbarkJS = { - onReady: function(cb) { - if (typeof (__embarkContext) === 'undefined') { - return cb(); - } - return __embarkContext.execWhenReady(cb); - } -}; - -EmbarkJS.isNewWeb3 = function(web3Obj) { - var _web3 = web3Obj || (new Web3()); - if (typeof(_web3.version) === "string") { - return true; - } - return parseInt(_web3.version.api.split('.')[0], 10) >= 1; -}; - -EmbarkJS.Contract = function(options) { - var self = this; - var i, abiElement; - var ContractClass; - - this.abi = options.abi; - this.address = options.address; - this.gas = options.gas; - this.code = '0x' + options.code; - //this.web3 = options.web3 || web3; - this.web3 = options.web3; - if (!this.web3 && typeof (web3) !== 'undefined') { - this.web3 = web3; - } else if (!this.web3) { - this.web3 = window.web3; - } - - if (EmbarkJS.isNewWeb3(this.web3)) { - ContractClass = new this.web3.eth.Contract(this.abi, this.address); - ContractClass.options.data = this.code; - ContractClass.options.from = this.from || this.web3.eth.defaultAccount; - ContractClass.abi = ContractClass.options.abi; - ContractClass.address = this.address; - ContractClass.gas = this.gas; - - let originalMethods = Object.keys(ContractClass); - - ContractClass._jsonInterface.forEach((abi) => { - if (originalMethods.indexOf(abi.name) >= 0) { - console.log(abi.name + " is a reserved word and cannot be used as a contract method, property or event"); - return; - } - - if (!abi.inputs) { - return; - } - - let numExpectedInputs = abi.inputs.length; - - if (abi.type === 'function' && abi.constant) { - ContractClass[abi.name] = function() { - let options = {}, cb = null, args = Array.from(arguments || []).slice(0, numExpectedInputs); - if (typeof (arguments[numExpectedInputs]) === 'function') { - cb = arguments[numExpectedInputs]; - } else if (typeof (arguments[numExpectedInputs]) === 'object') { - options = arguments[numExpectedInputs]; - cb = arguments[numExpectedInputs + 1]; - } - - let ref = ContractClass.methods[abi.name]; - let call = ref.apply(ref, ...arguments).call; - return call.apply(call, []); - }; - } else if (abi.type === 'function') { - ContractClass[abi.name] = function() { - let options = {}, cb = null, args = Array.from(arguments || []).slice(0, numExpectedInputs); - if (typeof (arguments[numExpectedInputs]) === 'function') { - cb = arguments[numExpectedInputs]; - } else if (typeof (arguments[numExpectedInputs]) === 'object') { - options = arguments[numExpectedInputs]; - cb = arguments[numExpectedInputs + 1]; - } - - let ref = ContractClass.methods[abi.name]; - let send = ref.apply(ref, args).send; - return send.apply(send, [options, cb]); - }; - } else if (abi.type === 'event') { - ContractClass[abi.name] = function(options, cb) { - let ref = ContractClass.events[abi.name]; - return ref.apply(ref, [options, cb]); - } - } - }); - - return ContractClass; - } else { - ContractClass = this.web3.eth.contract(this.abi); - - this.eventList = []; - - if (this.abi) { - for (i = 0; i < this.abi.length; i++) { - abiElement = this.abi[i]; - if (abiElement.type === 'event') { - this.eventList.push(abiElement.name); - } - } - } - - var messageEvents = function() { - this.cb = function() {}; - }; - - messageEvents.prototype.then = function(cb) { - this.cb = cb; - }; - - messageEvents.prototype.error = function(err) { - return err; - }; - - this._originalContractObject = ContractClass.at(this.address); - this._methods = Object.getOwnPropertyNames(this._originalContractObject).filter(function(p) { - // TODO: check for forbidden properties - if (self.eventList.indexOf(p) >= 0) { - - self[p] = function() { - var promise = new messageEvents(); - var args = Array.prototype.slice.call(arguments); - args.push(function(err, result) { - if (err) { - promise.error(err); - } else { - promise.cb(result); - } - }); - - self._originalContractObject[p].apply(self._originalContractObject[p], args); - return promise; - }; - return true; - } else if (typeof self._originalContractObject[p] === 'function') { - self[p] = function(_args) { - var args = Array.prototype.slice.call(arguments); - var fn = self._originalContractObject[p]; - var props = self.abi.find((x) => x.name == p); - - var promise = new Promise(function(resolve, reject) { - args.push(function(err, transaction) { - promise.tx = transaction; - if (err) { - return reject(err); - } - - var getConfirmation = function() { - self.web3.eth.getTransactionReceipt(transaction, function(err, receipt) { - if (err) { - return reject(err); - } - - if (receipt !== null) { - return resolve(receipt); - } - - setTimeout(getConfirmation, 1000); - }); - }; - - if (typeof(transaction) !== "string" || props.constant) { - resolve(transaction); - } else { - getConfirmation(); - } - }); - - fn.apply(fn, args); - }); - - return promise; - }; - return true; - } - return false; - }); - } -}; - -EmbarkJS.Contract.prototype.deploy = function(args, _options) { - var self = this; - var contractParams; - var options = _options || {}; - - contractParams = args || []; - - contractParams.push({ - from: this.web3.eth.accounts[0], - data: this.code, - gas: options.gas || 800000 - }); - - var contractObject = this.web3.eth.contract(this.abi); - - var promise = new Promise(function(resolve, reject) { - contractParams.push(function(err, transaction) { - if (err) { - reject(err); - } else if (transaction.address !== undefined) { - resolve(new EmbarkJS.Contract({ - abi: self.abi, - code: self.code, - address: transaction.address - })); - } - }); - - // returns promise - // deploys contract - // wraps it around EmbarkJS.Contract - contractObject["new"].apply(contractObject, contractParams); - }); - - - return promise; -}; - -EmbarkJS.Contract.prototype.new = EmbarkJS.Contract.prototype.deploy; - -EmbarkJS.Contract.prototype.at = function(address) { - return new EmbarkJS.Contract({ abi: this.abi, code: this.code, address: address }); -}; - -EmbarkJS.Contract.prototype.send = function(value, unit, _options) { - var options, wei; - if (typeof unit === 'object') { - options = unit; - wei = value; - } else { - options = _options || {}; - wei = this.web3.toWei(value, unit); - } - - options.to = this.address; - options.value = wei; - - this.web3.eth.sendTransaction(options); -}; - -EmbarkJS.Storage = {}; - -EmbarkJS.Storage.Providers = {}; - -EmbarkJS.Storage.saveText = function(text) { - if (!this.currentStorage) { - throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); - } - return this.currentStorage.saveText(text); -}; - -EmbarkJS.Storage.get = function(hash) { - if (!this.currentStorage) { - throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); - } - return this.currentStorage.get(hash); -}; - -EmbarkJS.Storage.uploadFile = function(inputSelector) { - if (!this.currentStorage) { - throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); - } - return this.currentStorage.uploadFile(inputSelector); -}; - -EmbarkJS.Storage.getUrl = function(hash) { - if (!this.currentStorage) { - throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); - } - return this.currentStorage.getUrl(hash); -}; - -EmbarkJS.Storage.registerProvider = function(providerName, obj) { - EmbarkJS.Storage.Providers[providerName] = obj; -}; - -EmbarkJS.Storage.setProvider = function(provider, options) { - let providerObj = this.Providers[provider]; - - if (!providerObj) { - throw new Error('Unknown storage provider'); - } - - this.currentStorage = providerObj; - - return providerObj.setProvider(options); -}; - -EmbarkJS.Storage.isAvailable = function(){ - if (!this.currentStorage) { - throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); - } - return this.currentStorage.isAvailable(); -}; - -EmbarkJS.Messages = {}; - -EmbarkJS.Messages.Providers = {}; - -EmbarkJS.Messages.registerProvider = function(providerName, obj) { - EmbarkJS.Messages.Providers[providerName] = obj; -}; - -EmbarkJS.Messages.setProvider = function(provider, options) { - let providerObj = this.Providers[provider]; - - if (!providerObj) { - throw new Error('Unknown messages provider'); - } - - this.currentMessages = providerObj; - - return providerObj.setProvider(options); -}; - -EmbarkJS.Messages.isAvailable = function(){ - return this.currentMessages.isAvailable(); -}; - -EmbarkJS.Messages.sendMessage = function(options) { - if (!this.currentMessages) { - throw new Error('Messages provider not set; e.g EmbarkJS.Messages.setProvider("whisper")'); - } - return this.currentMessages.sendMessage(options); -}; - -EmbarkJS.Messages.listenTo = function(options, callback) { - if (!this.currentMessages) { - throw new Error('Messages provider not set; e.g EmbarkJS.Messages.setProvider("whisper")'); - } - return this.currentMessages.listenTo(options, callback); -}; - -EmbarkJS.Names = {}; - -EmbarkJS.Names.Providers = {}; - -EmbarkJS.Names.registerProvider = function(providerName, obj) { - EmbarkJS.Names.Providers[providerName] = obj; -} - -EmbarkJS.Names.setProvider = function(provider, options) { - let providerObj = this.Providers[provider]; - - if (!providerObj) { - throw new Error('Unknown name system provider'); - } - - this.currentNameSystems = providerObj; - - return providerObj.setProvider(options); -}; - -// resolve resolves a name into an identifier of some kind -EmbarkJS.Names.resolve = function(name) { - if (!this.currentNameSystems) { - throw new Error('Name system provider not set; e.g EmbarkJS.Names.setProvider("ens")'); - } - return this.currentNameSystems.resolve(name); -} - -// the reverse of resolve, resolves using an identifier to get to a name -EmbarkJS.Names.lookup = function(identifier) { - if (!this.currentNameSystems) { - throw new Error('Name system provider not set; e.g EmbarkJS.Names.setProvider("ens")'); - } - return this.currentNameSystems.lookup(identifier); -} - -// To Implement - -/* -// register a name -EmbarkJS.Names.register = function(name, options) { - -} -*/ - -EmbarkJS.Utils = { - fromAscii: function(str) { - var _web3 = new Web3(); - return _web3.utils ? _web3.utils.fromAscii(str) : _web3.fromAscii(str); - }, - toAscii: function(str) { - var _web3 = new Web3(); - return _web3.utils.toAscii(str); - } -}; - -module.exports = EmbarkJS; diff --git a/lib/contracts/code_generator.js b/lib/contracts/code_generator.js index 719205024..9cae038c4 100644 --- a/lib/contracts/code_generator.js +++ b/lib/contracts/code_generator.js @@ -285,7 +285,9 @@ class CodeGenerator { buildEmbarkJS(cb) { const self = this; - let embarkjsCode = fs.readFileSync(fs.embarkPath('js/embark.js')).toString(); + let embarkjsCode = "import EmbarkJS from 'embarkjs';"; + embarkjsCode += "\nexport default EmbarkJS;"; + embarkjsCode += "\nglobal.EmbarkJS = EmbarkJS"; let code = ""; async.waterfall([ @@ -363,16 +365,16 @@ class CodeGenerator { function getImports(web3Location, next) { web3Location = web3Location.replace(/\\/g, '/'); // Import paths must always have forward slashes code += "\nimport Web3 from '" + web3Location + "';\n"; + code += "\nglobal.Web3 = Web3;\n"; - code += "\n if (typeof web3 !== 'undefined') {"; - code += "\n } else {"; + code += "\n if (typeof web3 === 'undefined') {"; code += "\n var web3 = new Web3();\n"; code += "\n }"; + code += "\nglobal.web3 = web3;\n"; let providerCode = self.generateProvider(false); code += providerCode; code += "\nglobal.__embarkContext = __mainContext.__loadManagerInstance;\n"; - code += "\nwindow.web3 = web3;\n"; code += "\nexport default web3;\n"; next(null, code); } diff --git a/lib/contracts/code_templates/main-context.js.ejs b/lib/contracts/code_templates/main-context.js.ejs index 557e62b65..77152eb84 100644 --- a/lib/contracts/code_templates/main-context.js.ejs +++ b/lib/contracts/code_templates/main-context.js.ejs @@ -1 +1,3 @@ -var __mainContext = __mainContext || this; +var __mainContext = __mainContext || ( + this ? this : typeof self !== 'undefined' ? self : void 0 +); diff --git a/lib/contracts/code_templates/web3-connector.js.ejs b/lib/contracts/code_templates/web3-connector.js.ejs index 2cf5f9b52..b272786e7 100644 --- a/lib/contracts/code_templates/web3-connector.js.ejs +++ b/lib/contracts/code_templates/web3-connector.js.ejs @@ -1,4 +1,3 @@ -__mainContext.web3 = undefined; __reduce(<%- connectionList %>,function(prev, value, next) { if (prev === false) { return next(null, false); diff --git a/lib/core/engine.js b/lib/core/engine.js index 844efd469..71b8ec2ed 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -100,6 +100,7 @@ class Engine { this.events.emit("status", "Building Assets"); const Pipeline = require('../pipeline/pipeline.js'); const pipeline = new Pipeline({ + env: this.env, buildDir: this.config.buildDir, contractsFiles: this.config.contractsFiles, assetFiles: this.config.assetFiles, diff --git a/lib/pipeline/pipeline.js b/lib/pipeline/pipeline.js index d86253487..4b9170d64 100644 --- a/lib/pipeline/pipeline.js +++ b/lib/pipeline/pipeline.js @@ -4,14 +4,10 @@ const ProcessLauncher = require('../process/processLauncher'); const utils = require('../utils/utils.js'); const constants = require('../constants'); -require("babel-preset-react"); -require("babel-preset-es2015"); -require("babel-preset-es2016"); -require("babel-preset-es2017"); - class Pipeline { constructor(options) { + this.env = options.env; this.buildDir = options.buildDir; this.contractsFiles = options.contractsFiles; this.assetFiles = options.assetFiles; @@ -115,7 +111,7 @@ class Pipeline { } } }); - webpackProcess.send({action: constants.pipeline.init, options: {}}); + webpackProcess.send({action: constants.pipeline.init, options: {env: self.env}}); webpackProcess.send({action: constants.pipeline.build, file, importsList}); webpackProcess.once('result', constants.pipeline.built, (msg) => { diff --git a/lib/pipeline/webpackProcess.js b/lib/pipeline/webpackProcess.js index ca917d3c6..759b11572 100644 --- a/lib/pipeline/webpackProcess.js +++ b/lib/pipeline/webpackProcess.js @@ -5,19 +5,21 @@ const fs = require('../core/fs'); const constants = require('../constants'); const HardSourceWebpackPlugin = require('hard-source-webpack-plugin'); const ProcessWrapper = require('../process/processWrapper'); +const path = require('path'); let webpackProcess; class WebpackProcess extends ProcessWrapper { + constructor(options) { + super(options); + this.env = options.env; + } + build(file, importsList, callback) { const self = this; let realCwd; async.waterfall([ - function findImports(next) { - self.webpackRun(file.filename, {}, false, importsList, false, next); - }, - function changeCwd(next) { realCwd = utils.pwd(); process.chdir(fs.embarkPath('')); @@ -25,7 +27,7 @@ class WebpackProcess extends ProcessWrapper { }, function runWebpack(next) { - self.webpackRun(file.filename, {}, true, importsList, true, next); + self.webpackRun(file.filename, {}, true, importsList, true, realCwd, next); }, function changeCwdBack(next) { @@ -38,15 +40,25 @@ class WebpackProcess extends ProcessWrapper { }); } - - webpackRun(filename, options, includeModules, importsList, detectErrors, callback) { + webpackRun(filename, options, includeModules, importsList, detectErrors, realCwd, callback) { + const self = this; let defaultOptions = { + mode: self.env === 'production' ? 'production' : 'none', + // devtool: self.env === 'development' ? 'source-map' : false, + // pipeline would need to copy .map files to dist/ target dir + // note: generating full source maps ('source-map') roughly doubles build time entry: fs.dappPath(filename), output: { + globalObject: 'typeof self !== \'undefined\' ? self : this', + libraryExport: 'default', libraryTarget: 'umd', path: fs.dappPath('.embark'), - filename: filename + filename: filename, + umdNamedDefine: true }, + // profile: true, + // stats: 'verbose', + // note: generating and writing to disk verbose stats increases build time resolve: { alias: importsList, modules: [ @@ -54,10 +66,18 @@ class WebpackProcess extends ProcessWrapper { fs.dappPath('node_modules') ] }, - externals: function (context, request, callback) { - callback(); - }, - plugins: [new HardSourceWebpackPlugin()] + plugins: [ + new HardSourceWebpackPlugin({ + cacheDirectory: fs.dappPath('node_modules/.cache/hard-source'), + // ufglify (wp mode: production) will still save its cache in embark's node_modules/.cache/ + environmentHash: { + root: fs.dappPath() + } + }), + new HardSourceWebpackPlugin.ExcludeModulePlugin( + [{test: /app[\\/]|contracts[\\/]/}] + ) + ] }; let webpackOptions = utils.recursiveMerge(defaultOptions, options); @@ -82,27 +102,83 @@ class WebpackProcess extends ProcessWrapper { loader: "babel-loader", exclude: /(node_modules|bower_components)/, options: { - presets: ['babel-preset-es2016', 'babel-preset-es2017', 'babel-preset-react'].map(require.resolve), - plugins: ["babel-plugin-webpack-aliases"].map(require.resolve), + presets: [ + [ + "@babel/preset-env", { + modules: false, + targets: { + browsers: ["last 1 version", "not dead", "> 0.2%"] + } + } + ], + "@babel/preset-react" + ].map(pkg => { + if (Array.isArray(pkg)) { + let _pkg = pkg[0]; + pkg[0] = require.resolve(_pkg); + return pkg; + } else { + return require.resolve(pkg); + } + }), + plugins: [ + "@babel/plugin-transform-runtime", + "babel-plugin-webpack-aliases" + ].map(require.resolve), compact: false } } ] }; + + let dappBabelrc = path.join(realCwd, '.babelrc'); + if (fs.existsSync(dappBabelrc)) { + webpackOptions.module.rules[3].options.extends = dappBabelrc; + } } webpack(webpackOptions).run((err, stats) => { - if (err) { - console.error(err); - } - if (!detectErrors) { - return callback(); - } - - if (stats.hasErrors()) { - return callback(stats.toJson().errors.join("\n")); - } - callback(); + async.waterfall([ + function checkStatsError(next) { + if (err) { + console.error(err); + return next(err); + } + if (!detectErrors) { + return next(); + } + if (stats.hasErrors()) { + return next( + stats.toJson(webpackOptions.stats).errors.join("\n") + ); + } + next(); + }//, + // function writeStatsReport(next) { + // if (detectErrors) { + // self._log('info', 'writing file '+ ('.embark/stats.report').bold.dim); + // } + // fs.writeFile( + // path.join(fs.dappPath('.embark'), 'stats.report'), + // stats.toString(webpackOptions.stats), + // next + // ); + // }, + // function writeStatsJSON(next) { + // if (detectErrors) { + // self._log('info','writing file '+ ('.embark/stats.json').bold.dim); + // } + // fs.writeFile( + // path.join(fs.dappPath('.embark'), 'stats.json'), + // JSON.stringify(stats.toJson(webpackOptions.stats)), + // next + // ); + // } + // note: to visualize the stats info in a browser, do... + // `npx webpack-bundle-analyzer /.embark/stats.json` + ], (err) => { + callback(err); + }); }); } } diff --git a/lib/process/processWrapper.js b/lib/process/processWrapper.js index c5886d336..30108fe45 100644 --- a/lib/process/processWrapper.js +++ b/lib/process/processWrapper.js @@ -65,7 +65,7 @@ class ProcessWrapper { _log(type, ...messages) { const isHardSource = messages.some(message => { - return (typeof message === 'string' && message.indexOf('hard-source') > -1); + return (typeof message === 'string' && message.indexOf('hardsource') > -1); }); if (isHardSource) { return; diff --git a/lib/tests/test.js b/lib/tests/test.js index f13f01135..060fe34ff 100644 --- a/lib/tests/test.js +++ b/lib/tests/test.js @@ -9,7 +9,7 @@ const AccountParser = require('../contracts/accountParser'); const Provider = require('../contracts/provider'); const utils = require('../utils/utils'); -const EmbarkJS = require('../../js/embark_node'); +const EmbarkJS = require('embarkjs'); function getSimulator() { try { diff --git a/package.json b/package.json index 5c3e4cd91..7918d50f7 100644 --- a/package.json +++ b/package.json @@ -21,15 +21,14 @@ "url": "https://github.com/embark-framework/embark.git" }, "dependencies": { + "@babel/core": "7.0.0-beta.54", + "@babel/plugin-transform-runtime": "7.0.0-beta.54", + "@babel/preset-env": "7.0.0-beta.54", + "@babel/preset-react": "7.0.0-beta.54", "ascii-table": "0.0.9", "async": "^2.0.1", - "babel-core": "^6.26.0", - "babel-loader": "^7.1.2", + "babel-loader": "^8.0.0-beta.4", "babel-plugin-webpack-aliases": "^1.1.3", - "babel-preset-es2015": "^6.24.1", - "babel-preset-es2016": "^6.24.1", - "babel-preset-es2017": "6.24.1", - "babel-preset-react": "^6.24.1", "bip39": "^2.5.0", "chokidar": "^2.0.3", "clone-deep": "^4.0.0", @@ -39,6 +38,7 @@ "decompress": "^4.2.0", "deep-equal": "^1.0.1", "ejs": "^2.5.8", + "embarkjs": "^0.2.0", "eth-ens-namehash": "^2.0.8", "eth-lib": "^0.2.8", "ethereumjs-wallet": "^0.6.0", @@ -48,7 +48,7 @@ "fs-extra": "^2.0.0", "ganache-cli": "6.1.0", "globule": "^1.1.0", - "hard-source-webpack-plugin": "^0.6.6", + "hard-source-webpack-plugin": "^0.11.1", "http-proxy": "^1.17.0", "http-shutdown": "^1.2.0", "i18n": "^0.8.3", @@ -79,7 +79,7 @@ "uuid": "^3.2.1", "viz.js": "^1.8.1", "web3": "1.0.0-beta.34", - "webpack": "^3.10.0", + "webpack": "^4.16.1", "window-size": "^1.1.0" }, "author": "Iuri Matias ", diff --git a/test/processLauncher.js b/test/processLauncher.js index 64f83590f..d77f8f252 100644 --- a/test/processLauncher.js +++ b/test/processLauncher.js @@ -3,6 +3,7 @@ const assert = require('assert'); const sinon = require('sinon'); const TestLogger = require('../lib/tests/test_logger'); const ProcessLauncher = require('../lib/process/processLauncher'); +const path = require('path'); describe('ProcessWrapper', () => { let processLauncher; @@ -11,7 +12,7 @@ describe('ProcessWrapper', () => { sinon.stub(ProcessLauncher.prototype, '_subscribeToMessages'); processLauncher = new ProcessLauncher({ logger: new TestLogger({}), - modulePath: 'test.js' + modulePath: path.join(__dirname, 'test.js') }); }); diff --git a/test/test.js b/test/test.js new file mode 100644 index 000000000..540af6ec1 --- /dev/null +++ b/test/test.js @@ -0,0 +1 @@ +// empty -- loaded by ./processLauncher.js