@aimee-blue/ab-service-kit
Version:
Aimee Blue Service Template
181 lines (143 loc) • 7.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.serviceSetupInWatchMode = serviceSetupInWatchMode;
var _chokidar = _interopRequireDefault(require("chokidar"));
var _path = _interopRequireWildcard(require("path"));
var _rxjs = require("rxjs");
var _operators = require("rxjs/operators");
var _shared = require("../shared");
var _fsExtra = require("fs-extra");
var _clearModule = require("../shared/clearModule");
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
if (process.env.NODE_ENV === 'production') {
throw new Error('This file should not be imported in production');
}
const watchMultiple = patterns => {
if ((0, _shared.isUnitTest)() || (0, _shared.isIntegrationTest)()) {
return (0, _rxjs.never)();
}
const logger = (0, _shared.defaultBasicLogger)();
return new _rxjs.Observable(subscriber => {
const watcher = _chokidar.default.watch(patterns, {
ignorePermissionErrors: true
});
const onChange = file => {
logger.log('Change detected for', file);
subscriber.next(file);
};
const onError = err => {
subscriber.error(err);
};
const onClose = () => {
subscriber.complete();
};
watcher.on('change', onChange).on('error', onError).on('close', onClose);
return () => {
watcher.close().catch(err => {
logger.log('Couldnt close file watcher', err);
});
};
});
};
let teardownOldServer = async () => {
const logger = (0, _shared.defaultBasicLogger)();
logger.log('Dummy teardown was called ... odd');
return;
};
const moduleInfo = mod => ({
filePath: _path.default.relative('./', mod.filename),
mod
});
function mainModule() {
if (!require.main) {
throw new Error('No require.main defined');
}
return require.main;
}
function allChildModules(startFrom = mainModule()) {
return (0, _rxjs.of)(moduleInfo(startFrom)).pipe(stream => {
const set = new Set(); // sometimes modules circularly reference each other :(
const uniqueModules = arr => {
const items = arr.filter(item => !set.has(item));
items.forEach(set.add.bind(set));
return items;
};
return stream.pipe((0, _operators.expand)(data => (0, _rxjs.from)(uniqueModules(data.mod.children)).pipe((0, _operators.map)(moduleInfo), (0, _operators.filter)(pair => !pair.filePath.includes('node_modules')))));
});
}
function findModule(fullPathToJs, startFrom = mainModule()) {
const compareTo = (0, _path.resolve)(_path.default.normalize(fullPathToJs));
return (0, _rxjs.concat)(allChildModules(startFrom), (0, _rxjs.from)(Object.entries(require.cache).filter(entry => !entry[0].includes('node_modules')).map(entry => entry[1]).filter(_shared.isTruthy).map(module => moduleInfo(module)))).pipe( //
(0, _operators.find)(result => {
const resolvedPath = (0, _path.resolve)(_path.default.normalize(result.filePath));
return resolvedPath === compareTo;
}));
}
function allParentModules(module) {
return (0, _rxjs.defer)(() => {
return (0, _rxjs.of)(module.parent).pipe((0, _operators.filter)(_shared.isTruthy), (0, _operators.expand)(next => next.parent ? (0, _rxjs.of)(next.parent) : (0, _rxjs.empty)()), (0, _operators.map)(mod => moduleInfo(mod)));
});
}
function requireSetupModule(moduleId) {
// eslint-disable-next-line
const result = require(moduleId);
if (typeof result !== 'object') {
throw new Error('Resolved to a non-object');
}
if ('default' in result) {
return result.default;
}
return result;
}
async function serviceSetupInWatchMode(setupFilePath, setup) {
const initialConfig = requireSetupModule(setupFilePath);
const logger = (0, _shared.defaultBasicLogger)();
teardownOldServer = await setup(initialConfig); // please note that changes to this pattern will probably need changes to `watchServerCode` function
// to detect .ts file locations correctly
const WATCH_PATTERNS = initialConfig.watchPatterns || ['lib/**/*.js', '.env', '.env.local'];
const subscription = (0, _rxjs.defer)(() => {
logger.log(`🔍 Watching for file changes in ${WATCH_PATTERNS.join(', ')}`);
return watchMultiple(WATCH_PATTERNS);
}).pipe((0, _operators.mergeMap)(filePath => (0, _rxjs.from)((0, _fsExtra.pathExists)((0, _path.join)(process.cwd(), filePath)).catch(() => false).then(exists => ({
exists,
filePath,
resolved: (0, _path.join)(process.cwd(), filePath)
})))), (0, _operators.filter)(pair => {
if (!pair.exists) {
logger.log(`Cannot resolve changes to ${pair.filePath} (tried ${pair.resolved}), ignoring`);
}
return pair.exists;
}), (0, _operators.mergeMap)(fileInfo => findModule(fileInfo.resolved).pipe((0, _operators.filter)(_shared.isTruthy), (0, _operators.concatMap)(mod => (0, _rxjs.concat)((0, _rxjs.of)(mod), allParentModules(mod.mod))), (0, _operators.toArray)())), (0, _operators.filter)(mods => mods.length > 0), (0, _operators.concatMap)(mods => (0, _rxjs.from)(teardownOldServer('watch-mode')).pipe((0, _operators.mapTo)(mods))), (0, _operators.concatMap)(mods => {
for (const mod of mods) {
if (mod.mod.id === '.') {
// we do not reload the main module
continue;
}
if ((0, _path.dirname)(mod.mod.id) === __dirname) {
continue;
}
(0, _clearModule.clearModule)(mod.mod.id);
}
if (!mods.find(item => item.filePath === setupFilePath)) {
(0, _clearModule.clearModule)(setupFilePath);
}
return (0, _rxjs.defer)(() => (0, _rxjs.from)(setup(requireSetupModule(setupFilePath)).then(teardown => {
teardownOldServer = teardown;
return Promise.resolve();
})));
}), (0, _operators.catchError)((err, self) => {
logger.log('💥 Watching error, will wait for 2sec before restart ... ', err);
return (0, _rxjs.timer)(2000).pipe((0, _operators.switchMapTo)(self));
})).subscribe(() => {
return;
}, err => logger.log('💥 Watching error', err), () => logger.log('Watching stopped'));
return async mode => {
subscription.unsubscribe();
await teardownOldServer(mode);
};
}
//# sourceMappingURL=watchServerCode.js.map