123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- var path = require('path'),
- fs = require('fs'),
- XEventEmitter = require('./utils/xevents'),
- clearRequire = require('./utils/clear-require'),
- readPackageJson = require('./utils/read-packagejson');
- var BundleContext = require('./bundle-context');
- var log = require('hlogger').createLogger('bundle-manager');
- function solveBundleName(inpath) {
- var name = path.basename(inpath);
- if(name == "index.js") {
- name = path.basename(path.dirname(inpath));
- } else {
- name = path.basename(inpath,".js");
- }
- return name;
- };
- // Common registry
- class BundleManager {
- constructor(opts) {
- // Control events
- this.config = opts || {};
-
- this.events = new XEventEmitter();
- // Global channel
- this.globalEvents = new XEventEmitter();
- this.stat = {
- modulesRegistered:0,
- modulesUnRegistered:0
- };
- this.registry = {};
- //this.registry = [];
- }
- generateId() {
- var id=0;
- // Slow -- by fetching all ids everytime
- do { id++; } while(this.get(id) != null); // Slow but one timer
- return id;
- }
- loadDefaultBundles() {
- var corePath = path.join(__dirname,"../bundles");
- fs.readdir(corePath, (err,dir) => {
- for( var file of dir ) {
- this.load(path.join(corePath,file));
- }
- });
- }
- getBundleByInstance(instance) {
- //return this.registry.find((el) => el.instance == instance);
- for(var k in this.registry) {
- if(this.registry[k].instance == instance) {
- return this.registry[k];
- }
- }
- return null;
- }
- getBundleById(id) {
- //return this.registry.find((el) => el.id == id);
- for(var k in this.registry) {
- if(this.registry[k].id == id) {
- return this.registry[k];
- }
- }
- return null;
- }
- getBundle(name) {
- //return this.registry.find((el) => el.name == name);
- return this.registry[name];
- }
- get(obj) {
- if(isNaN(obj) == false) {
- return this.getBundleById(obj);
- }
- if(typeof(obj) == "string") {
- return this.getBundle(obj);
- }
- if(obj instanceof BundleContext) {
- return obj;
- }
- return this.getBundleByInstance(obj);
- }
- load(modPath) {
- var modName = solveBundleName(modPath);
- this.register({name: modName,bundle:modPath});
- }
- register(opts) {
- var {id,name,bundle,autostart} = opts;
-
- var instance;
- var modulePath;
- var mod = bundle;
- var version = "unknown";
- if(this.getBundle(name) != undefined) {
- log.error(name + " Already exists");
- return;
- }
- if(typeof(bundle) == "string") {
- var modPath= path.resolve(bundle);
- var modInfo = readPackageJson(bundle);
- try {
- mod = require(modPath);
- } catch(e) {
- console.error(e);
- return;
- }
- if(mod == undefined) {
- log.error("Undefined module at: " + bundle);
- }
- modulePath = modPath;
- }
-
- if(mod.bundleFactory != undefined) {
- instance = new mod.bundleFactory()
- } else {
- instance = mod;
- }
- id = id || this.generateId();
- // Simplify this
- var context = new BundleContext({
- id: id,
- name:name,
- manager:this,
- instance: instance,
- modulePath:modulePath,
- pkgInfo: modInfo,
- version:version
- });
-
- this.stat.modulesRegistered++;
- this.registry[name] = context;
- //this.registry.push(context);
- if(autostart != false) {
- context.start();
- }
- }
- unregister(obj) {
- var context = this.get(obj);
- if(context == null) {
- log.error("Context not found for: " + obj);
- return;
- }
- context.stop();
- // Unload require
- if(context.modulePath != undefined) {
- clearRequire(context.modulePath);
- }
- /*this.registry = this.registry.filter((ctx) => {
- return ctx != context;
- });*/
- delete this.registry[context.name];
- this.stat.modulesUnRegistered++;
- }
- // Batch call
- call(name,args) {
- var [ctxName, method] = name.split(":")
- var matchCtx = new RegExp(ctxName);
- var fretList = [];
- for(var ctxn in this.registry) {
- var ctx = this.registry[ctxn];
- if(!matchCtx.test(ctx.name)) {
- continue;
- }
- var ret = { name:ctx.name}
- if(ctx.instance[method] == undefined || typeof(ctx.instance[method]) != "function") {
- ret.result = 0;
- ret.error = "method not found";
- } else {
- ret.result = ctx.instance[method](args);
- }
- fretList.push(ret);
- }
- return fretList;
- }
- with(args,cb) {
- var mods = args;
- /*if(typeof(args[args.length-1]) != "function") {
- throw new Error("Deprecated having callback on argument");
- }*/
- if(!Array.isArray(args)) {
- mods = [args];
- }
- // Move this to manager directly
- var iParam = [];
- var ret = { // we could create generic out of this, its not a promise
- success: true,
- /*do: function(cb) {
- if(this.success) cb.apply(cb,iParam);
- return this;
- },*/
- else: function(cb) {
- if(!this.success)cb();
- return this;
- }
- }
- for(var v of mods) {
- if(v == undefined) throw new Error("What?");
- var ctx = this.get(v);
- if(ctx == null || ctx.info.state != 1) {
- ret.success = false;
- break;
- } // Early bail
- iParam.push(ctx.instance);
- }
- if(ret.success) cb(...iParam);
- return ret;
- }
- }
- module.exports = BundleManager;
|