aboutsummaryrefslogtreecommitdiff
path: root/node_modules/time-require/src
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-05-28 00:38:50 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-05-28 00:40:43 +0200
commit7fff4499fd915bcea3fa93b1aa8b35f4fe7a6027 (patch)
tree6de9a1aebd150a23b7f8c273ec657a5d0a18fe3e /node_modules/time-require/src
parent963b7a41feb29cc4be090a2446bdfe0c1f1bcd81 (diff)
add linting (and some initial fixes)
Diffstat (limited to 'node_modules/time-require/src')
-rw-r--r--node_modules/time-require/src/requireHook.js93
-rw-r--r--node_modules/time-require/src/timeRequire.js140
2 files changed, 233 insertions, 0 deletions
diff --git a/node_modules/time-require/src/requireHook.js b/node_modules/time-require/src/requireHook.js
new file mode 100644
index 000000000..ebafbb603
--- /dev/null
+++ b/node_modules/time-require/src/requireHook.js
@@ -0,0 +1,93 @@
+/**
+ * requireHook - module wrapping a function that register require() listener and returns hook/unhook control
+ *
+ * @author Ciprian Popa (cyparu)
+ * @since 0.0.1
+ * @version 0.0.1
+ */
+
+"use strict";
+
+var Module = require("module").Module,
+ _load = Module._load,
+ _hookedAt, _listener;
+
+/**
+ * Module hooker function that will replace Module._load and invoke the _listener with module and timing information
+ *
+ * @function _hooker
+ */
+function _hooker(name, parent) {
+ var timeIn = Date.now(),
+ exports = _load.apply(Module, arguments),
+ timeOut = Date.now(),
+ mod = parent.children[parent.children.length - 1]; // should be the last loaded children
+ // call the listener
+ _listener({
+ name: name,
+ parent: parent,
+ module: mod,
+ filename: mod ? mod.filename : name,
+ exports: exports,
+ requiredOn: timeIn,
+ startedIn: timeOut - timeIn
+ });
+ return exports;
+}
+
+/**
+ * Hook Node's require() so the configured callback will be invocked with additional module and time loading information information
+ *
+ * @param {Function} [listener] - optional listener if
+ * @method hook
+ */
+function _hook(listener) {
+ if (typeof listener !== "undefined") {
+ if (typeof listener !== "function") {
+ throw new Error("The optional parameter for hook() should be a function but was " + (typeof listener));
+ }
+ // set the listener
+ _listener = listener;
+ }
+ // set the hoocker loader
+ Module._load = _hooker;
+ // mark hooked time
+ _hookedAt = new Date();
+}
+
+/**
+ * Unhook Node's require() to the original function
+ *
+ * @method unhook
+ */
+function _unhook() {
+ // set the original loader
+ Module._load = _load;
+ // reset hooking time
+ _hookedAt = undefined;
+}
+
+/**
+ * Export a function that set the callback and return hook/unhook control functionality
+ *
+ * @function
+ * @param {Function} listener - require() listener
+ * @param {Boolean} [autohook=true] - optional flag telling if the hooking will be started automatically
+ * @return hook/unhook control function
+ */
+module.exports = function(listener, autohook) {
+ if (typeof listener !== "function") {
+ throw new Error("The hooking function should be set");
+ }
+ // set the listener
+ _listener = listener;
+ // if autohook (by default),
+ if (autohook !== false) {
+ _hook();
+ }
+ return {
+ hookedAt: _hookedAt,
+ hook: _hook,
+ unhook: _unhook
+ };
+};
diff --git a/node_modules/time-require/src/timeRequire.js b/node_modules/time-require/src/timeRequire.js
new file mode 100644
index 000000000..0ba556fab
--- /dev/null
+++ b/node_modules/time-require/src/timeRequire.js
@@ -0,0 +1,140 @@
+/**
+ * timeRequire - measure the time to load all the subsequnt modules by hoocking require() calls
+ *
+ * @author Ciprian Popa (cyparu)
+ * @since 0.0.1
+ * @version 0.0.1
+ */
+
+"use strict";
+
+var // setup vars
+ requireData = [],
+ write = process.stdout.write.bind(process.stdout),
+ relative = require("path").relative,
+ cwd = process.cwd(),
+ // require hooker should be first module loaded so all the other requires should count as well
+ /* jshint -W003 */
+ hook = require("./requireHook")(_hooker),
+ table = require("text-table"),
+ dateTime = require("date-time"),
+ prettyMs = require("pretty-ms"),
+ chalk = require("chalk"),
+ // extra locals
+ DEFAULT_COLUMNS = 80,
+ BAR_CHAR = process.platform === "win32" ? "■" : "▇",
+ sorted = hasArg("--sorted") || hasArg("--s"),
+ treshold = (hasArg("--verbose") || hasArg("--V")) ? 0.0: 0.01, // TODO - configure treshold using CLI ?
+ EXTRA_COLUMNS = sorted ? 24 : 20;
+
+function hasArg(arg) {
+ return process.argv.indexOf(arg) !== -1;
+}
+
+function pad(count, seq) {
+ return (count > 1) ? new Array(count).join(seq) : "";
+}
+
+function log(str) {
+ write(str + "\n", "utf8");
+}
+
+/**
+ * Callback/listener used by requireHook hook to collect all the modules in their loading order
+ */
+function _hooker(data) {
+ var filename = relative(cwd, data.filename);
+ // use the shortest name
+ if (filename.length > data.filename) {
+ filename = data.filename;
+ }
+ requireData.push({
+ order: requireData.length, // loading order
+ time: data.startedIn, // time
+ label: data.name + " (" + filename + ")"
+// name: data.name,
+// filename: filename
+ });
+}
+
+function formatTable(tableData, totalTime) {
+ var NAME_FILE_REX = /(.+)( \(.+\))/,
+ maxColumns = process.stdout.columns || DEFAULT_COLUMNS,
+ validCount = 0,
+ longestRequire = tableData.reduce(function(acc, data) {
+ var avg = data.time / totalTime;
+ if (avg < treshold) {
+ return acc;
+ }
+ validCount++;
+ return Math.max(acc, data.label.length);
+ }, 0),
+ maxBarWidth = (longestRequire > maxColumns / 2) ? ((maxColumns - EXTRA_COLUMNS) / 2) : (maxColumns - (longestRequire + EXTRA_COLUMNS)),
+ processedTableData = [],
+ counter, maxOrderChars;
+
+ function shorten(name) {
+ var nameLength = name.length,
+ partLength, start, end;
+ if (name.length < maxBarWidth) {
+ return name;
+ }
+ partLength = Math.floor((maxBarWidth - 3) / 2);
+ start = name.substr(0, partLength + 1);
+ end = name.substr(nameLength - partLength);
+ return start.trim() + "..." + end.trim();
+ }
+
+ function createBar(percentage) {
+ var rounded = Math.round(percentage * 100);
+ return ((rounded === 0) ? "0" : (pad(Math.ceil(maxBarWidth * percentage) + 1, BAR_CHAR) + " " + rounded)) + "%";
+ }
+
+ // sort the data if needed
+ if (sorted) {
+ tableData.sort(function(e1, e2) {
+ return e2.time - e1.time;
+ });
+ }
+ // initialize the counter
+ counter = 1;
+ // get num ber of chars for padding
+ maxOrderChars = tableData.length.toString().length;
+ // push the header
+ processedTableData.push(["#" + (sorted ? " [order]" : ""), "module", "time", "%"]);
+ tableData.forEach(function(data) {
+ var avg = data.time / totalTime,
+ counterLabel, label, match;
+ // slect just data over the threshold
+ if (avg >= treshold) {
+ counterLabel = counter++;
+ // for sorted collumns show the order loading with padding
+ if (sorted) {
+ counterLabel += pad(maxOrderChars - data.order.toString().length + 1, " ") + " [" + data.order + "]";
+ }
+ label = shorten(data.label);
+ match = label.match(NAME_FILE_REX);
+ if (match) {
+ label = chalk.green(match[1]) + match[2];
+ }
+ processedTableData.push([counterLabel, label, chalk.yellow(prettyMs(data.time)), chalk.blue(createBar(avg))]);
+ }
+ });
+
+ return table(processedTableData, {
+ align: ["r", "l", "r", "l"],
+ stringLength: function(str) {
+ return chalk.stripColor(str).length;
+ }
+ });
+}
+
+// hook process exit to display the report at the end
+process.once("exit", function() {
+ var startTime = hook.hookedAt,
+ totalTime = Date.now() - startTime.getTime();
+ log("\n\n" + chalk.underline("Start time: " + chalk.yellow("(" + dateTime(startTime) + ")") + " [treshold=" + (treshold * 100) + "%" + (sorted ? ",sorted" : "") + "]"));
+ log(formatTable(requireData, totalTime));
+ log(chalk.bold.blue("Total require(): ") + chalk.yellow(requireData.length));
+ log(chalk.bold.blue("Total time: ") + chalk.yellow(prettyMs(totalTime)));
+});