UNPKG

impress

Version:

Enterprise application server for Node.js

87 lines (78 loc) 2.54 kB
'use strict'; const { metarhia } = require('./deps.js'); const { Place } = require('./place.js'); const bus = require('./bus.js'); class Code extends Place { constructor(name, application) { super(name, application); this.tree = {}; } async stop() { for (const moduleName of Object.keys(this.tree)) { const module = this.tree[moduleName]; if (typeof module.stop === 'function') { await this.application.execute(module.stop); } } } stopModule(name, module) { const timeout = this.application.config.server.timeouts.watch; setTimeout(() => { if (this.tree[name] !== undefined) return; this.application.execute(module.stop); }, timeout); } set(relPath, unit) { const names = metarhia.metautil.parsePath(relPath); let level = this.tree; const last = names.length - 1; for (let depth = 0; depth <= last; depth++) { const name = names[depth]; let next = level[name]; if (depth === last) { if (unit === null) { if (name === 'stop') this.stopModule(names[0], level); delete level[name]; return; } next = unit; unit.parent = level; } if (next === undefined) next = { parent: level }; level[name] = next; if (depth === 1 && name === 'start') { if (unit.constructor.name === 'AsyncFunction') { this.application.starts.push(unit); } else { const msg = `${relPath} expected to be async function`; this.application.console.error(msg); } } level = next; } } delete(filePath) { const relPath = filePath.substring(this.path.length + 1); this.set(relPath, null); } async change(filePath) { if (!filePath.endsWith('.js')) return; if (filePath.startsWith('.eslint')) return; const { application, path, name } = this; const isTest = filePath.endsWith('.test.js'); if (isTest && application.mode !== 'test') return; const options = { context: application.sandbox, filename: filePath }; try { const { exports } = await metarhia.metavm.readScript(filePath, options); const relPath = filePath.substring(path.length + 1); const exp = name === 'bus' ? bus.prepare(exports, application) : exports; this.set(relPath, exp); if (isTest) application.tests.push(exp); } catch (error) { if (error.code !== 'ENOENT') { application.console.error(error.stack); } } } } module.exports = { Code };