truffle
Version:
Truffle - Simple development framework for Ethereum
565 lines (478 loc) • 15.2 kB
JavaScript
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ 97610:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
__webpack_require__(20406);
const IPC = (__webpack_require__(39813).IPC);
const Ganache = __webpack_require__(11651);
const path = __webpack_require__(71017);
const debug = __webpack_require__(15158);
const util = __webpack_require__(73837);
/*
* Loggers
*/
const ipcDebug = debug("chain:ipc");
/*
* Options
*/
// This script is expected to take two arguments: The first a networkName string,
// the second an options string encoded as base64.
// The options string is decoded, parsed, & then passed to Ganache.server().
const args = process.argv.slice(2);
const ipcNetwork = args[0];
const base64OptionsString = args[1];
const optionsBuffer = Buffer.from(base64OptionsString, "base64");
let optionsString = optionsBuffer.toString();
let options;
try {
options = JSON.parse(optionsString);
} catch (e) {
throw new Error(
"Fatal: Error parsing arguments; please contact the Truffle developers for help."
);
}
options.time = options.time ? new Date(options.time) : new Date();
/*
* Logging
*/
// constructor
class Logger {
constructor() {
this.messages = [];
this.nextSubscriberID = 1;
this.subscribers = {};
}
// subscribe to log events with provided callback
// sends prior unsent messages, as well as new messages
// returns `unsubscribe` cleanup function
subscribe(callback) {
// flush messages
const messages = this.messages;
this.messages = [];
messages.forEach(message => {
callback(message);
});
// save subscriber
const subscriberID = this.nextSubscriberID++;
this.subscribers[subscriberID] = callback;
// return cleanup func
const unsubscribe = () => {
delete this.subscribers[subscriberID];
};
return unsubscribe;
}
// log a message to be sent to all active subscribers
// buffers if there are no active subscribers (to send on first subscribe)
log(...messages) {
const subscriberIDs = Object.keys(this.subscribers);
const formattedMessages = util.formatWithOptions(
{ colors: true },
...messages
);
if (subscriberIDs.length === 0) {
this.messages.push(formattedMessages);
return;
}
subscriberIDs.forEach(subscriberID => {
const callback = this.subscribers[subscriberID];
callback(formattedMessages);
});
}
}
/*
* Supervisor
*/
// constructor - accepts an object to assign to `ipc.config`
class Supervisor {
constructor(ipcConfig) {
// init IPC
this.ipc = new IPC();
// set config
Object.keys(ipcConfig).forEach(key => {
this.ipc.config[key] = ipcConfig[key];
});
this.mixins = [];
}
// include mixin
use(mixin) {
this.mixins.push(mixin);
}
// dispatch event to all relevant mixins (ones that define `event` method)
handle(event, args) {
args = Array.prototype.slice.call(args);
this.mixins.forEach(mixin => {
if (mixin[event]) {
mixin[event].apply(mixin, [this].concat(args));
}
});
}
// start the IPC server and hook up all the mixins
start() {
const self = this;
const ipc = this.ipc;
// socket filename
const dirname = ipc.config.socketRoot;
const basename = `${ipc.config.appspace}${ipc.config.id}`;
const servePath = path.join(dirname, basename);
ipc.serve(servePath, function () {
self.handle("start", arguments);
ipc.server.on("connect", function () {
self.handle("connect", arguments);
});
ipc.server.on("socket.disconnected", function () {
self.handle("disconnect", arguments);
});
});
ipc.server.start();
}
// external interface for mixin to emit socket events
emit(socket, message, data, options = {}) {
options.silent = options.silent || false;
// possibly override silent
const currentlySilent = this.ipc.config.silent;
if (options.silent) {
this.ipc.config.silent = true;
}
this.ipc.server.emit(socket, message, data);
// reset
this.ipc.config.silent = currentlySilent;
}
// external interface for mixin to exit
exit() {
this.ipc.server.stop();
this.handle("exit", arguments);
}
}
/*
* Lifecycle
* (quit on last connection)
*/
class LifecycleMixin {
// start counting active connections
start(_supervisor) {
this.connections = 0;
}
// increment
connect(_supervisor) {
this.connections++;
}
// decrement - invoke supervisor exit if no connections remain
disconnect(supervisor) {
this.connections--;
if (this.connections <= 0) {
supervisor.exit();
}
}
}
/*
* Ganache Server
*/
// constructor - accepts options for Ganache
class GanacheMixin {
constructor(options, ganacheConsoleLogger) {
this.ganache = Ganache.server(options);
this.ganacheConsoleLogger = ganacheConsoleLogger;
}
// start Ganache and capture promise that resolves when ready
start(_supervisor) {
this.ready = new Promise((accept, reject) => {
this.ganache.listen(options.port, options.hostname, (err, state) => {
if (err) {
reject(err);
}
accept(state);
});
});
}
// wait for Ganache to be ready then emit signal to client socket
connect(supervisor, socket) {
this.ready.then(() => {
supervisor.emit(socket, "truffle.ready");
// hook into ganache console.log events
this.ganache.provider.on("ganache:vm:tx:console.log", ({ logs }) => {
this.ganacheConsoleLogger.log(
// Format and colorize ganache log data which may or may not
// include a format string as the first argument.
util.formatWithOptions({ colors: true }, ...logs)
);
});
});
}
// cleanup Ganache process on exit
exit(_supervisor) {
this.ganache
.close()
.then(() => (process.exitCode = 0))
.catch(err => {
console.error(err.stack || err);
process.exitCode = 1;
});
}
}
/*
* Logging over IPC
*/
// constructor - takes Logger instance and message key (e.g. `truffle.ipc.log`)
class LoggerMixin {
constructor(logger, message) {
this.logger = logger;
this.message = message;
}
// on connect, subscribe client socket to logger
connect(supervisor, socket) {
const unsubscribe = this.logger.subscribe(data => {
supervisor.emit(socket, this.message, data, { silent: true });
});
socket.on("close", unsubscribe);
}
}
/*
* Process event handling
*/
process.on("uncaughtException", ({ stack }) => {
console.error(stack);
process.exit(1);
});
/*
* Main
*/
const ipcLogger = new Logger();
const ganacheLogger = new Logger();
const ganacheConsoleLogger = new Logger();
const supervisor = new Supervisor({
appspace: "truffle.",
id: ipcNetwork,
retry: 1500,
logger: ipcLogger.log.bind(ipcLogger)
});
ipcLogger.subscribe(ipcDebug);
options.logger = { log: ganacheLogger.log.bind(ganacheLogger) };
ganacheConsoleLogger.log = ganacheConsoleLogger.log.bind(ganacheConsoleLogger);
const ganacheMixin = new GanacheMixin(options, ganacheConsoleLogger);
supervisor.use(new LifecycleMixin());
supervisor.use(ganacheMixin);
supervisor.use(new LoggerMixin(ipcLogger, "truffle.ipc.log"));
supervisor.use(new LoggerMixin(ganacheLogger, "truffle.ganache.log"));
supervisor.use(new LoggerMixin(ganacheConsoleLogger, "truffle.solidity.log"));
supervisor.start();
/***/ }),
/***/ 11651:
/***/ ((module) => {
;
module.exports = require("ganache");
/***/ }),
/***/ 71891:
/***/ ((module) => {
;
module.exports = require("dgram");
/***/ }),
/***/ 57147:
/***/ ((module) => {
;
module.exports = require("fs");
/***/ }),
/***/ 41808:
/***/ ((module) => {
;
module.exports = require("net");
/***/ }),
/***/ 22037:
/***/ ((module) => {
;
module.exports = require("os");
/***/ }),
/***/ 71017:
/***/ ((module) => {
;
module.exports = require("path");
/***/ }),
/***/ 24404:
/***/ ((module) => {
;
module.exports = require("tls");
/***/ }),
/***/ 76224:
/***/ ((module) => {
;
module.exports = require("tty");
/***/ }),
/***/ 73837:
/***/ ((module) => {
;
module.exports = require("util");
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ id: moduleId,
/******/ loaded: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = __webpack_modules__;
/******/
/******/ // the startup function
/******/ __webpack_require__.x = () => {
/******/ // Load entry module and return exports
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, [5158,406,9813], () => (__webpack_require__(97610)))
/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__);
/******/ return __webpack_exports__;
/******/ };
/******/
/************************************************************************/
/******/ /* webpack/runtime/chunk loaded */
/******/ (() => {
/******/ var deferred = [];
/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => {
/******/ if(chunkIds) {
/******/ priority = priority || 0;
/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
/******/ deferred[i] = [chunkIds, fn, priority];
/******/ return;
/******/ }
/******/ var notFulfilled = Infinity;
/******/ for (var i = 0; i < deferred.length; i++) {
/******/ var [chunkIds, fn, priority] = deferred[i];
/******/ var fulfilled = true;
/******/ for (var j = 0; j < chunkIds.length; j++) {
/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {
/******/ chunkIds.splice(j--, 1);
/******/ } else {
/******/ fulfilled = false;
/******/ if(priority < notFulfilled) notFulfilled = priority;
/******/ }
/******/ }
/******/ if(fulfilled) {
/******/ deferred.splice(i--, 1)
/******/ var r = fn();
/******/ if (r !== undefined) result = r;
/******/ }
/******/ }
/******/ return result;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/ensure chunk */
/******/ (() => {
/******/ __webpack_require__.f = {};
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = (chunkId) => {
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
/******/ __webpack_require__.f[key](chunkId, promises);
/******/ return promises;
/******/ }, []));
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/get javascript chunk filename */
/******/ (() => {
/******/ // This function allow to reference async chunks and sibling chunks for the entrypoint
/******/ __webpack_require__.u = (chunkId) => {
/******/ // return url for filenames based on template
/******/ return "" + chunkId + ".bundled.js";
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/node module decorator */
/******/ (() => {
/******/ __webpack_require__.nmd = (module) => {
/******/ module.paths = [];
/******/ if (!module.children) module.children = [];
/******/ return module;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/require chunk loading */
/******/ (() => {
/******/ // no baseURI
/******/
/******/ // object to store loaded chunks
/******/ // "1" means "loaded", otherwise not loaded yet
/******/ var installedChunks = {
/******/ 8507: 1
/******/ };
/******/
/******/ __webpack_require__.O.require = (chunkId) => (installedChunks[chunkId]);
/******/
/******/ var installChunk = (chunk) => {
/******/ var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;
/******/ for(var moduleId in moreModules) {
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(runtime) runtime(__webpack_require__);
/******/ for(var i = 0; i < chunkIds.length; i++)
/******/ installedChunks[chunkIds[i]] = 1;
/******/ __webpack_require__.O();
/******/ };
/******/
/******/ // require() chunk loading for javascript
/******/ __webpack_require__.f.require = (chunkId, promises) => {
/******/ // "1" is the signal for "already loaded"
/******/ if(!installedChunks[chunkId]) {
/******/ if(true) { // all chunks have JS
/******/ installChunk(require("./" + __webpack_require__.u(chunkId)));
/******/ } else installedChunks[chunkId] = 1;
/******/ }
/******/ };
/******/
/******/ // no external install chunk
/******/
/******/ // no HMR
/******/
/******/ // no HMR manifest
/******/ })();
/******/
/******/ /* webpack/runtime/startup chunk dependencies */
/******/ (() => {
/******/ var next = __webpack_require__.x;
/******/ __webpack_require__.x = () => {
/******/ __webpack_require__.e(5158);
/******/ __webpack_require__.e(406);
/******/ __webpack_require__.e(9813);
/******/ return next();
/******/ };
/******/ })();
/******/
/************************************************************************/
/******/
/******/ // run startup
/******/ var __webpack_exports__ = __webpack_require__.x();
/******/ var __webpack_export_target__ = exports;
/******/ for(var i in __webpack_exports__) __webpack_export_target__[i] = __webpack_exports__[i];
/******/ if(__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true });
/******/
/******/ })()
;
//# sourceMappingURL=chain.bundled.js.map