'use strict';
// const periodicSchema = require('./schema');
// const periodicModel = require('./model');
// const periodicConnect = require('./connect');
const Promisie = require('promisie');
const express = require('express');
const events = require('events');
const cache = require('memory-cache');
const CoreData = require('periodicjs.core.data');
const CoreFiles = require('periodicjs.core.files');
const CoreUtilities = require('periodicjs.core.utilities');
// const CoreController = require('periodicjs.core.controller');
const periodicInit = require('./init');
const periodicExtension = require('./extension');
const periodicCrud = require('./crud');
const periodicUtils = require('./utilities');
const periodicProxyHandler = require('./periodicProxyHandler');
/**
* periodic singleton class
*
* @class Periodic
*/
class Periodic {
/**
* Creates an instance of periodic.
* @param {any} [options={}]
* @param {boolean} options.debug use debugging logs
* @param {String} options.app_root the path to the application's root directory
* @return {object} proxied periodic singleton object
*
* @memberOf Periodic
*/
constructor(options = {}) {
//https://www.npmjs.com/package/express-react-engine
this.config = Object.assign({
debug: false,
setMaxListeners: 0,
app_root: process.cwd(),
configuration: {},
// settings: {},
}, options);
events.EventEmitter.defaultMaxListeners = this.config.setMaxListeners;
this.__class = {
init:periodicInit,
extension:periodicExtension,
crud:periodicCrud,
utils:periodicUtils,
proxyHandler:periodicProxyHandler,
};
this.settings = {};
this.utilities = periodicUtils;
this.cache = cache;
this.express = express;
this.workers;
this.numWorkers;
this.cluster;
this.app = express();
// this.connections = new Map();
this.status = new events.EventEmitter();
this.transforms = {
pre: {
CONNECT: {},
DELETE: {},
GET: {},
HEAD: {},
OPTIONS: {},
POST: {},
PUT: {},
},
post: {
CONNECT: {},
DELETE: {},
GET: {},
HEAD: {},
OPTIONS: {},
POST: {},
PUT: {},
},
};
this.controllers = {
core: new Map(),
extension: new Map(),
container: new Map(),
preTransforms: periodicUtils.middleware.preTransforms(this),
postTransforms: periodicUtils.middleware.postTransforms(this),
};
this.resources = {
standard_models: [],
databases: {
extensions: {},
container: {},
},
commands: {
extensions: new Map(),
container: new Map(),
},
};
this.locals = {
core: new Map(),
extensions: new Map(),
container: new Map(),
};
this.routers = new Map();
this.containers = new Map();
this.extensions = new Map();
this.servers = new Map();
this.datas = new Map();
this.dbs = new Map();
this.models = new Map();
this.tasks = {
resetExtensions: periodicInit.config.loadExtensions.bind(this),
installExtension: periodicExtension.install.installExtension.bind(this),
uninstallExtension: periodicExtension.uninstall.uninstallExtension.bind(this),
};
this.crud = {
config: {
create: periodicCrud.config.create.bind(this),
update: periodicCrud.config.update.bind(this),
remove: periodicCrud.config.remove.bind(this),
init: periodicCrud.config.init.bind(this),
get: periodicUtils.mock.tempPromise,
list: periodicUtils.mock.tempPromise,
},
ext: {
create: periodicCrud.ext.create.bind(this),
update: periodicUtils.mock.tempPromise,
remove: periodicCrud.ext.remove.bind(this),
get: periodicUtils.mock.tempPromise,
list: periodicCrud.ext.list.bind(this),
init: periodicCrud.ext.init.bind(this, false),
},
con: {
create: periodicUtils.mock.tempPromise,
update: periodicUtils.mock.tempPromise,
remove: periodicUtils.mock.tempPromise,
get: periodicUtils.mock.tempPromise,
list: periodicUtils.mock.tempPromise,
init: periodicCrud.ext.init.bind(this, 'container'),
},
};
this.logger = console;
this.logger.silly = console.log;
this.logger.debug = console.log;
this.logger.verbose = console.info;
this.logger.info = console.info;
this.logger.warn = console.info;
this.logger.error = console.error;
// this.db = undefined;
// this.app = {}; //express app
this.core = {
data: CoreData,
utilities: new CoreUtilities(this),
mailer: {},
files: CoreFiles,
// controller:
};
// console.log('this.core.controller',this.core.controller);
// this.controller = peroidicController.bind(this);
// this.container = peroidicContainer.bind(this);
// this.extension = peroidicExtension.bind(this);
return new Proxy(this, periodicProxyHandler.call(this));
}
/**
* initialize a periodic application, by creating folder structure, using a CLI application, cluster & fork the main thread, start the web server, use a socket server
* @param {Boolean} options.debug log debug output
* @param {String} options.app_root the path to the application's root directory
* @param {Object} options.settings set initial settings before configurations are loaded
*
* @returns {Promise} fully resolved periodic instance
* @memberOf periodic
*/
init(options = {}) {
process.setMaxListeners(this.config.setMaxListeners || 0);
this.status.emit('initializing', true);
this.config = Object.assign({}, this.config, options);
return new Promise((resolve, reject) => {
const completInit = periodicInit.runtime.completeInitialization.bind(this, resolve, reject);
Promisie.series([
periodicInit.timer.startTimer.bind(this),
periodicInit.setUpFolderStructure.bind(this),
periodicInit.config.loadConfiguration.bind(this),
periodicInit.runtime.configRuntimeEnvironment.bind(this),
periodicInit.config.loadAppSettings.bind(this),
periodicInit.logger.configureLogger.bind(this),
periodicInit.config.loadExtensions.bind(this),
periodicInit.config.setupGenericCoreMailer.bind(this),
periodicInit.config.setupGenericCoreController.bind(this),
periodicExtension.setup.setupExtensions.bind(this),
periodicExtension.setup.setupContainer.bind(this),
periodicInit.config.loadDatabases.bind(this),
periodicInit.config.loadExternalRouters.bind(this),
periodicInit.logger.catchProcessErrors.bind(this),
periodicInit.express.initializeExpress.bind(this),
periodicInit.cli.run.bind(this),
periodicInit.cluster.forkProcess.bind(this),
periodicInit.server.initializeServers.bind(this),
periodicInit.timer.endTimer.bind(this),
]).then(resolve)
.catch(completInit);
});
}
}
module.exports = Periodic;