331 lines
9.8 KiB
JavaScript
331 lines
9.8 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _ProjectUtils;
|
|
|
|
function _load_ProjectUtils() {
|
|
return _ProjectUtils = _interopRequireWildcard(require('../project/ProjectUtils'));
|
|
}
|
|
|
|
var _lodash;
|
|
|
|
function _load_lodash() {
|
|
return _lodash = require('lodash');
|
|
}
|
|
|
|
var _EnvironmentHelper;
|
|
|
|
function _load_EnvironmentHelper() {
|
|
return _EnvironmentHelper = require('../tools/EnvironmentHelper');
|
|
}
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
class PackagerLogsStream {
|
|
|
|
constructor({
|
|
projectRoot,
|
|
getCurrentOpenProjectId,
|
|
updateLogs,
|
|
onStartBuildBundle,
|
|
onProgressBuildBundle,
|
|
onFinishBuildBundle
|
|
}) {
|
|
this._resetState = () => {
|
|
this._logsToAdd = [];
|
|
this._chunkID = 0;
|
|
};
|
|
|
|
this._handlePackagerEvent = chunk => {
|
|
let { msg } = chunk;
|
|
|
|
if (!msg.type) {
|
|
return;
|
|
} else if (msg.type && msg.type.match(/^bundle_/)) {
|
|
this._handleBundleTransformEvent(chunk);
|
|
return;
|
|
}
|
|
|
|
if (msg.type === 'dep_graph_loading') {
|
|
chunk.msg = 'Loading dependency graph.'; // doesn't seem important to log this
|
|
} else if (msg.type == 'dep_graph_loaded') {
|
|
chunk.msg = 'Dependency graph loaded.'; // doesn't seem important to log this
|
|
} else if (msg.type === 'transform_cache_reset') {
|
|
chunk.msg = 'Your JavaScript transform cache is empty, rebuilding (this may take a minute).';
|
|
} else if (msg.type === 'initialize_packager_started') {
|
|
chunk.msg = `Running packager on port ${msg.port}.`;
|
|
} else {
|
|
chunk.msg = '';
|
|
}
|
|
|
|
this._enqueueAppendLogChunk(chunk);
|
|
};
|
|
|
|
this._handleBundleTransformEvent = chunk => {
|
|
let { msg } = chunk;
|
|
|
|
if (msg.type === 'bundle_build_started') {
|
|
this._handleNewBundleTransformStarted(chunk);
|
|
} else if (msg.type === 'bundle_transform_progressed') {
|
|
this._bundleBuildChunkID ? this._handleUpdateBundleTransformProgress(chunk) : this._handleNewBundleTransformStarted(chunk);
|
|
} else if (msg.type === 'bundle_build_failed') {
|
|
if (!this._bundleBuildChunkID) {
|
|
return; // maybe?
|
|
} else {
|
|
this._handleUpdateBundleTransformProgress(chunk);
|
|
}
|
|
} else if (msg.type === 'bundle_build_done') {
|
|
if (!this._bundleBuildChunkID) {
|
|
return; // maybe?
|
|
} else {
|
|
this._handleUpdateBundleTransformProgress(chunk);
|
|
}
|
|
} else {
|
|
// Unrecognized bundle_* message!
|
|
}
|
|
};
|
|
|
|
this._handleNewBundleTransformStarted = chunk => {
|
|
if (this._bundleBuildChunkID) {
|
|
return;
|
|
}
|
|
|
|
this._bundleBuildChunkID = chunk._id;
|
|
this._bundleBuildStart = new Date();
|
|
chunk.msg = 'Building JavaScript bundle';
|
|
|
|
if (this._onStartBuildBundle) {
|
|
this._onStartBuildBundle();
|
|
} else {
|
|
this._enqueueAppendLogChunk(chunk);
|
|
}
|
|
};
|
|
|
|
this._handleUpdateBundleTransformProgress = progressChunk => {
|
|
let { msg } = progressChunk;
|
|
let percentProgress;
|
|
let bundleComplete = false;
|
|
let bundleError = false;
|
|
let bundleBuildEnd;
|
|
|
|
if (msg.type === 'bundle_build_done') {
|
|
percentProgress = 100;
|
|
bundleComplete = true;
|
|
bundleBuildEnd = new Date();
|
|
} else if (msg.type === 'bundle_build_failed') {
|
|
percentProgress = -1;
|
|
bundleComplete = true;
|
|
bundleError = new Error('Failed to build bundle');
|
|
bundleBuildEnd = new Date();
|
|
} else {
|
|
percentProgress = Math.floor(msg.transformedFileCount / msg.totalFileCount * 100);
|
|
}
|
|
|
|
if (this._onProgressBuildBundle) {
|
|
this._onProgressBuildBundle(percentProgress);
|
|
|
|
if (bundleComplete) {
|
|
this._onFinishBuildBundle && this._onFinishBuildBundle(bundleError, this._bundleBuildStart, bundleBuildEnd);
|
|
this._bundleBuildStart = null;
|
|
this._bundleBuildChunkID = null;
|
|
}
|
|
} else {
|
|
this._updateLogs(logs => {
|
|
if (!logs || !logs.length) {
|
|
return [];
|
|
}
|
|
|
|
logs.forEach(log => {
|
|
if (log._id === this._bundleBuildChunkID) {
|
|
if (percentProgress === -1) {
|
|
log.msg = `Building JavaScript bundle: error\n${msg.error.description || msg.error.message}`;
|
|
} else {
|
|
if (bundleComplete) {
|
|
let duration;
|
|
if (this._bundleBuildStart) {
|
|
duration = bundleBuildEnd - this._bundleBuildStart;
|
|
}
|
|
|
|
if (duration) {
|
|
log.msg = `Building JavaScript bundle: finished in ${duration}ms.`;
|
|
} else {
|
|
log.msg = `Building JavaScript bundle: finished.`;
|
|
}
|
|
} else {
|
|
log.msg = `Building JavaScript bundle: ${percentProgress}%`;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
if (bundleComplete) {
|
|
this._bundleBuildChunkID = null;
|
|
}
|
|
|
|
return [...logs];
|
|
});
|
|
}
|
|
};
|
|
|
|
this._enqueueFlushLogsToAdd = () => {
|
|
let func = () => {
|
|
this._updateLogs(logs => {
|
|
if (this._logsToAdd.length === 0) {
|
|
return logs;
|
|
}
|
|
|
|
let nextLogs = logs.concat(this._logsToAdd);
|
|
this._logsToAdd = [];
|
|
return nextLogs;
|
|
});
|
|
};
|
|
|
|
if ((0, (_EnvironmentHelper || _load_EnvironmentHelper()).isNode)()) {
|
|
func();
|
|
} else {
|
|
setImmediate(func);
|
|
}
|
|
};
|
|
|
|
this._legacyFormatter = chunk => {
|
|
if (typeof chunk.msg === 'object') {
|
|
return chunk;
|
|
}
|
|
|
|
if (chunk.msg.match(/Transforming modules/)) {
|
|
let progress = chunk.msg.match(/\d+\.\d+% \(\d+\/\d+\)/);
|
|
if (progress && progress[0]) {
|
|
chunk.msg = `Transforming modules: ${progress[0]}`;
|
|
}
|
|
}
|
|
|
|
return chunk.msg;
|
|
};
|
|
|
|
this._cleanUpNodeErrors = chunk => {
|
|
if (typeof chunk.msg === 'object') {
|
|
return chunk;
|
|
}
|
|
|
|
if (chunk.msg.match(/\(node:.\d*\)/)) {
|
|
// Example: (node:13817) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): SyntaxError: SyntaxError /Users/brent/universe/apps/new-project-template/main.js: Unexpected token (10:6)
|
|
// The first part of this is totally useless, so let's remove it.
|
|
if (chunk.msg.match(/UnhandledPromiseRejectionWarning/)) {
|
|
chunk.msg = chunk.msg.replace(/\(node:.*\(rejection .*\):/, '');
|
|
if (chunk.msg.match(/SyntaxError: SyntaxError/)) {
|
|
chunk.msg = chunk.msg.replace('SyntaxError: ', '');
|
|
}
|
|
} else if (chunk.msg.match(/DeprecationWarning/)) {
|
|
chunk.msg = '';
|
|
}
|
|
}
|
|
|
|
return chunk;
|
|
};
|
|
|
|
this._resetState();
|
|
this._projectRoot = projectRoot;
|
|
this._getCurrentOpenProjectId = getCurrentOpenProjectId || (() => 1);
|
|
this._updateLogs = updateLogs;
|
|
|
|
// Optional properties in case the consumer wants to handle updates on
|
|
// its own, eg: for a progress bar
|
|
this._onStartBuildBundle = onStartBuildBundle;
|
|
this._onProgressBuildBundle = onProgressBuildBundle;
|
|
this._onFinishBuildBundle = onFinishBuildBundle;
|
|
|
|
this._attachLoggerStream();
|
|
}
|
|
|
|
_attachLoggerStream() {
|
|
let projectId = this._getCurrentOpenProjectId();
|
|
|
|
(_ProjectUtils || _load_ProjectUtils()).attachLoggerStream(this._projectRoot, {
|
|
stream: {
|
|
write: chunk => {
|
|
if (chunk.tag !== 'packager' && chunk.tag !== 'expo') {
|
|
return;
|
|
} else if (this._getCurrentOpenProjectId() !== projectId) {
|
|
// TODO: We should be confident that we are properly unsubscribing
|
|
// from the stream rather than doing a defensive check like this.
|
|
return;
|
|
}
|
|
|
|
chunk = this._maybeParseMsgJSON(chunk);
|
|
chunk = this._formatMsg(chunk);
|
|
chunk = this._cleanUpNodeErrors(chunk);
|
|
chunk = this._attachChunkID(chunk);
|
|
|
|
if (typeof chunk.msg === 'object' || chunk.type === 'packager') {
|
|
this._handlePackagerEvent(chunk);
|
|
} else if (!chunk.msg.match(/\w/) || !chunk.msg || chunk.msg[0] === '{') {
|
|
return;
|
|
} else {
|
|
this._enqueueAppendLogChunk(chunk);
|
|
}
|
|
}
|
|
},
|
|
type: 'raw'
|
|
});
|
|
}
|
|
|
|
// This is where we handle any special packager events
|
|
|
|
|
|
// Any event related to bundle building is handled here
|
|
|
|
|
|
_enqueueAppendLogChunk(chunk) {
|
|
if (chunk.shouldHide) {
|
|
return;
|
|
} else {
|
|
this._logsToAdd.push(chunk);
|
|
this._enqueueFlushLogsToAdd();
|
|
}
|
|
}
|
|
|
|
_attachChunkID(chunk) {
|
|
this._chunkID++;
|
|
chunk._id = this._chunkID;
|
|
return chunk;
|
|
}
|
|
|
|
_maybeParseMsgJSON(chunk) {
|
|
try {
|
|
let parsedMsg = JSON.parse(chunk.msg);
|
|
chunk.msg = parsedMsg;
|
|
} catch (e) {
|
|
// Fallback to the <= SDK 15 version of formatting logs
|
|
let msg = this._legacyFormatter(chunk);
|
|
chunk.msg = msg;
|
|
}
|
|
|
|
return chunk;
|
|
}
|
|
|
|
// This message is just noise
|
|
// Fall back to the same formatting we did on SDK <= 15 before we had a custom
|
|
// reporter class.
|
|
_formatMsg(chunk) {
|
|
if (typeof chunk.msg === 'object') {
|
|
return chunk;
|
|
}
|
|
|
|
if (chunk.msg.match(/Looking for JS files in/)) {
|
|
chunk.msg = '';
|
|
} else if (chunk.msg.match(/^[\u001b]/)) {
|
|
chunk.msg = '';
|
|
}
|
|
|
|
chunk.msg = chunk.msg.replace(/\[\w{2}m/g, '');
|
|
chunk.msg = chunk.msg.replace(/\[2K/g, '');
|
|
chunk.msg = (0, (_lodash || _load_lodash()).trim)(chunk.msg);
|
|
return chunk;
|
|
}
|
|
}
|
|
exports.default = PackagerLogsStream;
|
|
//# sourceMappingURL=../__sourcemaps__/logs/PackagerLogsStream.js.map
|