st-bundle
Version:
CLI for watching and bundling SpringType projects.
114 lines (113 loc) • 5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("../utils/utils");
const hmr_content_1 = require("./hmr_content");
function generateUpdateId() {
return utils_1.fastHash(new Date().getTime().toString() + Math.random().toString());
}
function attachHMR(ctx) {
const config = ctx.config;
if (!config.hmr.enabled) {
return;
}
const devServer = ctx.devServer;
if (!devServer) {
return;
}
const tasks = {};
let lastGeneratedHMR = null;
let lastPayLoadID = null;
function softProjectUpdate(task, payload, ws_instance) {
// verify project files first
const log_pkg = '<bold><yellow>$pkg</yellow></bold>';
const time = utils_1.measureTime('hmr');
// check if its the last payLoadIDm, if so we want to reuse
if (payload.id === lastPayLoadID) {
ctx.log.info('hmr', 'Update <dim><$id></dim> has been reused', { id: payload.id });
devServer.clientSend('hmr', { packages: lastGeneratedHMR.packages, modules: lastGeneratedHMR.modules }, ws_instance);
}
else {
const clientProjectFiles = payload.summary['default'];
const { packages, modulesForUpdate } = task;
const projectPackage = packages.find(pkg => pkg.isDefaultPackage);
projectPackage.modules.forEach(module => {
// if client doesn't the compiled module
if (!clientProjectFiles.includes(module.props.fuseBoxPath)) {
ctx.log.info('hmr', `Module $name from ${log_pkg}`, {
name: module.props.fuseBoxPath,
pkg: 'default',
});
modulesForUpdate.push(module);
}
});
const packagesForUpdate = [];
// check vendor consistency
packages.forEach(pkg => {
if (pkg.isDefaultPackage)
return;
const name = pkg.getPublicName();
if (!payload.summary[name]) {
// here we need the entire package update
ctx.log.info('hmr', `Module ${log_pkg}`, { pkg: name });
packagesForUpdate.push(pkg);
return;
}
// check if some files are missing in the package
const packageFiles = payload.summary[name];
for (const i in pkg.modules) {
const module = pkg.modules[i];
if (!packageFiles.includes(module.props.fuseBoxPath)) {
// making a partial update
ctx.log.info('hmr', `Module $name ${log_pkg}`, {
name: module.props.fuseBoxPath,
pkg: name,
});
modulesForUpdate.push(module);
}
}
});
//save lastgenerated, so we can reuse
lastGeneratedHMR = hmr_content_1.generateHMRContent({ packages: packagesForUpdate, modules: modulesForUpdate, ctx: ctx });
lastPayLoadID = payload.id;
ctx.log.info('hmr', 'Update <dim><$id></dim> generated in $time', {
time: time.end(),
id: payload.id,
});
devServer.clientSend('hmr', { packages: lastGeneratedHMR.packages, modules: lastGeneratedHMR.modules }, ws_instance);
}
}
// here we recieve an update from client - the entire tree of its modules
devServer.onClientMessage((event, payload, ws_instance) => {
if (event === 'summary' && payload.id && tasks[payload.id]) {
softProjectUpdate(tasks[payload.id], payload, ws_instance);
}
});
ctx.ict.on('rebundle_complete', props => {
const { packages, file } = props;
if (file) {
const project = packages.find(pkg => pkg.isDefaultPackage);
let target = project.modules.find(module => module.props.absPath === file);
if (!target) {
// trying weak references
if (props.ctx.weakReferences.collection[file]) {
target = project.modules.find(module => module.props.absPath === props.ctx.weakReferences.collection[file][0]);
if (target) {
props.ctx.log.info('hmr', 'Reference mapped: $file', { file: target.props.absPath });
}
}
}
if (target) {
const task = {
packages: packages,
action: props.watcherAction,
modulesForUpdate: [target],
};
const id = generateUpdateId();
tasks[id] = task;
devServer.clientSend('get-summary', { id });
}
}
return props;
});
}
exports.attachHMR = attachHMR;