Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

okgo

Package Overview
Dependencies
Maintainers
2
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

okgo - npm Package Compare versions

Comparing version 0.0.3 to 0.0.4

lib/boot/okgo.js

16

lib/core/controller.js

@@ -12,3 +12,3 @@ /**

constructor(req, res){
let that = this;
let that = this
this.ctx = {

@@ -21,6 +21,6 @@ req: req,

set body( str ){
that.__render (str);
that.__render (str)
}
};
}
}

@@ -31,15 +31,15 @@

__render (stuff) {
let res = this.ctx.res;
let res = this.ctx.res
// 输出
if( !res || stuff === null || stuff === undefined ){
return;
return
}
let contype = 'text/html';
let contype = 'text/html'
if( typeof stuff == 'object' ){
stuff = JSON.stringify(stuff); // json 字符串
contype = 'application/json';
contype = 'application/json'
}
res.setHeader('Content-Type', contype+'; charset=utf-8')
res.writeHead(200)
res.end( stuff );
res.end( stuff )

@@ -46,0 +46,0 @@ }

@@ -8,3 +8,3 @@ /**

let hascnf = ( appInfo.conf && appInfo.conf.log ) || appInfo.conf.log;
let hascnf = ( appInfo.config && appInfo.config.log ) || appInfo.config.log;

@@ -11,0 +11,0 @@

@@ -41,3 +41,7 @@ /**

get app () {
return this.pwd + '/app'
}
}

@@ -44,0 +48,0 @@

@@ -30,5 +30,12 @@ /**

// POST 请求
path(...arg) {
this.request( 'POST', ...arg )
return this
}
// 请求
request (method, pathstr, ...middleware_and_control) {
let self = this
method = method.toUpperCase()

@@ -38,2 +45,3 @@

, append_middlewares = middleware_and_control
, is_static_file_server = (ctrlfunc instanceof app.StaticFileServer)
, is_static_url = ( typeof pathstr == 'string' && pathstr.indexOf('/:') == -1 )

@@ -52,7 +60,18 @@ , route_item = {

if( is_static_url ){
this._route_static[ pathstr ] = route_item
if (is_static_file_server) {
if( typeof pathstr == 'string' ){
ctrlfunc.dropPath( pathstr ) // 去掉前缀
pathstr = new RegExp(pathstr+'(.+)')
}
regPath()
}else if( is_static_url ){
this._route_static[ pathstr ] = route_item
}else{
regPath()
}
function regPath () {
route_item.regexp = pathRegexp(pathstr, route_item.regkeys);
this._route_regexp.push( route_item )
// app.log(route_item.regexp)
self._route_regexp.push( route_item )
}

@@ -59,0 +78,0 @@

@@ -0,3 +1,35 @@

const util_object = require('../util/object')
const util_array = require('../util/array')
const util_string = require('../util/string')
const util_fs = require('../util/fs')
const util_util = require('../util/util')
const fs = require('fs')
const path = require('path')
const querystring = require('querystring')
// 压缩模块
let UglifyJS = require("uglify-js")
let Less = require("less")
// 读取前端模块缓存
const srcModFileContentCache = {}
const srcOutputStaticPathCache = {}
/**
* 内核: 页面 显示
* 目录支持两级扫描
*/

@@ -8,17 +40,782 @@

// 页面类 加载
class ViewLoader
{
constructor (viewer) {
this.viewer = viewer
this._realconfig // config 缓存
}
get realConfig () {
if( ! this._realconfig ) {
let inh = this.viewer.inherit
if (inh) {
if (!app.view[inh]) {
throw new Error("not find base view <"+inh+"> to inherit")
}
this.viewer._parent = app.view[inh]
}
// app.view 已经按顺序初始化完成了
this._realconfig = ViewLoader.mergeInheritConfig (
this.viewer,
app.view[inh] || null
)
}
return this._realconfig
}
///////////////////////////////////////////////////////
// 合并继承 config 配置,返回新的配置
static mergeInheritConfig (self, baseViewer=null) {
let baseConfig = baseViewer
? baseViewer._loader.realConfig
: new Viewer().config
, selfConfig = self.config
// 预定义
selfConfig.output = selfConfig.output || {}
selfConfig.output.file = selfConfig.output.file || true // 默认为文件名
// 替换
ViewLoader.mergeConfigReplace(baseConfig, selfConfig,
[]
)
// 更新最大值
ViewLoader.mergeConfigNumberMax(baseConfig, selfConfig,
['version']
)
// 追加
ViewLoader.mergeConfigAppendArray(baseConfig, selfConfig,
['loader', 'request', 'src', ]
)
ViewLoader.mergeConfigAppendArray(baseConfig.lib, selfConfig.lib,
['css', 'js', ]
)
ViewLoader.mergeConfigAppendArray(baseConfig.output, selfConfig.output,
['plugin', ]
)
// 扩展
ViewLoader.mergeConfigExtendCoverObject(baseConfig, selfConfig,
['output', 'static', 'data', 'srcdeps', ]
)
// src 依赖处理
ViewLoader.sortDependentSrc(baseConfig, selfConfig)
// 返回新的
return baseConfig
}
// 得到处理过依赖的模块列表
static sortDependentSrc (baseConfig, config) {
let baserealsrc = baseConfig._realsrc || []
, localsrc = [...(config.src||[])]
, allsrcdeps = baseConfig.srcdeps
, isHandleDeps = {} // 已经处理过依赖的忽略
// 重复扫描处理依赖
while (true) {
let hdyilai = 0
for (let i=0; i<localsrc.length; i++) {
let one = localsrc[i]
, spx = one.split(':')
, realone = spx.length>1 ? spx[1] : spx[0]
, dps = allsrcdeps[realone]
// 查找依赖
if (dps && dps.length && !isHandleDeps[one]) {
localsrc.splice(i, 0, ...dps) // 插入依赖
i += dps.length
hdyilai ++ // 统计
isHandleDeps[one] = true
}
}
if(hdyilai===0 ){
break
}
}
// 依赖去重
localsrc = util_array.unique(localsrc)
// 结果
baseConfig._localsrc = localsrc
baseConfig._realsrc = baserealsrc.concat(localsrc)
//app.log(localsrc)
//app.log(baseConfig._realsrc)
}
// 追加配置
static mergeConfigAppendArray (base, extd, keys=[]) {
if(base && extd){
for (let i in keys) {
let k = keys[i]
if ( Array.isArray(base[k]) && Array.isArray(extd[k]) ) {
base[k] = base[k].concat(extd[k])
}
}
}
}
// 替换配置
static mergeConfigExtendCoverObject (base, extd, keys=[]) {
if(base && extd){
for (let i in keys) {
let k = keys[i]
if ( extd[k] !== undefined ) {
util_object.extend(base[k], extd[k], true) // cover
}
}
}
}
// 替换配置
static mergeConfigReplace (base, extd, keys=[]) {
if(base && extd){
for (let i in keys) {
let k = keys[i]
if ( extd[k] !== undefined ) {
base[k] = extd[k]
}
}
}
}
// 对比更新配置
static mergeConfigNumberMax (base, extd, keys=[]) {
if(base && extd){
for (let i in keys) {
let k = keys[i]
if ( extd[k] !== undefined ) {
if(extd[k] > base[k]){ // 以最大值为准
base[k] = extd[k]
}
}
}
}
}
}
// 页面组装类
class ViewAssemble
{
constructor (viewer, loader) {
this.viewer = viewer
this.loader = loader
// 组装好的静态文件
this.myHtm = ''
this.myJs = ''
this.myCss = '' // 追加的
this.distHtm = '' // 全部完整的
this.distJs = ''
this.distCss = ''
this.distMinHtm = '' // 压缩后的
this.distMinJs = '' // 压缩后的
this.distMinCss = '' // 压缩后的
this.distTplFunc = null // tppl func
// 加载数据
// await this.handleDist()
}
// 处理储存的文件
handleDist () {
let self = this
let config = this.loader.realConfig
return new Promise(async function( success ){
let refresh = config.output.refresh
, prepared = config.output.prepared && !refresh
, flph = self.storeStaticFilePath
let htm_cache = await self.loadAllSrc()
if ( ! htm_cache ) {
// 处理压缩
await self.compressAllDist()
htm_cache = self.distMinHtm || self.distHtm
// 结构框架
htm_cache = self.handleHtmlStructure( htm_cache )
htm_cache = self.handleReplaceValue( htm_cache )
// 存入磁盘
if( prepared ){
fs.writeFile(flph.htm, htm_cache, ()=>{})
}
}
//
if (prepared) {
}else{
// 输出 css 和 js 文件
//app.log('fs.writeFile(flph.css, self.distMinCss || self.distCss)')
//app.log(self.distMinJs || self.distJs)
let finalCssCon = self.handleReplaceValue( self.distMinCss || self.distCss )
, finalJsCon = self.handleReplaceValue( self.distMinJs || self.distJs )
if (refresh) {
// write js css
fs.writeFile(flph.css, finalCssCon, ()=>{
fs.writeFile(flph.js, finalJsCon, ()=>{
// app.log('// write js css ------------'+(self.distMinJs || self.distJs))
success()
})
})
}else{
// write js css
fs.writeFile(flph.css, finalCssCon, ()=>{})
fs.writeFile(flph.js, finalJsCon, ()=>{})
}
}
// tppl func
self.distTplFunc = util_util.tppl( htm_cache.toString() )
if (!refresh) {
success()
}
})
}
// 处理 html 结构
handleHtmlStructure (htmstr) {
let config = this.loader.realConfig
, uph = this.urlStaticFilePath
, head = '</head>'
, body = '</body>'
, static_url = config.static.url || '/static'
, query = config.static.query
, query_str = query ? '?'+querystring.stringify(query) : ''
, lib_css_elms = []
, lib_js_elms = []
, newDistHtm = htmstr
// app.log(query_str)
// css lib
for ( let i in config.lib.css ) {
let one = config.lib.css[i]
one = checkIsHttpUrl(one) ? one : path.join(static_url, 'libcss', one)
lib_css_elms.push(`<link href="${one}" rel="stylesheet" type="text/css" />\n` )
}
// js lib
for ( let i in config.lib.js ) {
let one = config.lib.js[i]
one = checkIsHttpUrl(one) ? one : path.join(static_url, 'libjs', one)
lib_js_elms.push(`<script src="${one}" type="text/javascript"></script>\n`)
}
// css & js
lib_css_elms.push(`<link href="${uph.css}${query_str}" rel="stylesheet" type="text/css" />\n`)
lib_js_elms.push(`<script src="${uph.js}${query_str}" type="text/javascript"></script>\n`)
// 替换
newDistHtm = newDistHtm.replace(head, lib_css_elms.join('')+head)
newDistHtm = newDistHtm.replace(body, lib_js_elms.join('')+body)
// 检查是否为 http
function checkIsHttpUrl(one){
return one.substr(0, 4)=='http'
}
// 返回值
return newDistHtm
}
// 替换变量
handleReplaceValue( stuff ) {
let config = this.loader.realConfig
for (let i in config.replace) {
if ( i.substr(0, 2) == '__' ){
continue // 私有属性
}
let value = config.replace[i]
stuff = util_string.replaceAll(stuff,
config.replace.__prefix + i + config.replace.__suffix,
value)
}
return stuff
}
// 压缩所有文件
async compressAllDist ( ) {
let self = this
let config = this.loader.realConfig
return new Promise(async function( success ){
// less 处理
Less.render(self.distCss, {
compress: config.output.compress // 是否压缩
}).then(function(output) {
// output.css = string of css
// output.map = string of sourcemap
// output.imports = array of string filenames of the imports referenced
self.distMinCss = output.css
okLess()
},
function(error) {
okLess()
});
// okLess
function okLess () {
if ( ! config.output.compress) {
return success()
}
// 如果需要压缩
// 压缩 html
self.distMinHtm = self.distHtm
.replace(/<!--[\w\W\r\n]*?-->/gmi, '')
.replace(/<!\S*!>/gmi, '') // <!libjs!>
.replace(/[\r\n\t\s]+/gmi, ' ')
.replace(/>\s+</gmi, '><')
.replace(/\s*\[:\s*/gmi, '[:')
.replace(/\s*:\]\s*/gmi, ':]')
.replace(/(^\s*)|(\s*$)/gmi, '') // drop 首尾空格
// app.log(self.distHtm)
// 压缩 js
UglifyJS = UglifyJS || require("uglify-js")
let resStuff = UglifyJS.minify(self.distJs, {
toplevel: config.output.compress=='topgrade', // 高级压缩
})
self.distMinJs = resStuff.code
// 成功
success()
}
})
}
// 获取文件地址
get urlStaticFilePath () {
let cnf = this.loader.realConfig
, base = cnf.static.url || '/static'
, vdir = cnf.version ? '/'+cnf.version : ''
, name = this.viewer._filename
return {
htm: base + '/htm' + vdir + '/' + name + '.htm',
css: base + '/css' + vdir + '/' + name + '.css',
js: base + '/js' + vdir + '/' + name + '.js',
}
}
// 获取保存文件路径
get storeStaticFilePath () {
let dir = this.storeStaticDir
, name = this.viewer._filename
if ( ! this._ststflpt) {
this._ststflpt = {
htm: dir.htm + '/' + name + '.htm',
css: dir.css + '/' + name + '.css',
js: dir.js + '/' + name + '.js',
}
}
return this._ststflpt
}
// 获取保存路径
get storeStaticDir () {
if ( ! this._ststpt) {
let cnf = this.loader.realConfig
, base = path.join(app.path.pwd, cnf.output.static || 'static')
, vdir = cnf.version ? '/'+cnf.version : ''
let p = this._ststpt = {
base: base,
htm: base + '/htm' + vdir,
css: base + '/css' + vdir,
js: base + '/js' + vdir,
}
if( ! srcOutputStaticPathCache[base] ){
srcOutputStaticPathCache[base] = true
// 创建目录
util_fs.mkdirs(p.js)
util_fs.mkdirs(p.css)
util_fs.mkdirs(p.htm)
}
}
return this._ststpt
}
// 读取加载文件
async loadAllSrc () {
let self = this
return new Promise(async function( success ){
let config = self.loader.realConfig
, realsrc = config._realsrc
, mysrc = config._localsrc
, parent = self.viewer._parent
// 如果是快速启动状态,则不读取 js 和 css 模块
if ( config.output.refresh || !config.output.prepared ) {
// 读取
let myJsAry = await self.readSrcModFileContents(mysrc, 'js')
, myCssAry = await self.readSrcModFileContents(mysrc, 'less') // less
// css js
self.myCss = myCssAry.map(x=>x[2]).join(' ')
self.myJs = myJsAry .map(x=>x[2]).join(' ')
self.distCss = (parent ? parent._assemble.distCss : '') + ' ' + self.myCss
self.distJs = (parent ? parent._assemble.distJs : '') + ' ' + self.myJs
}
// 如果是快速启动状态,则检查缓存
if ( config.output.prepared && !config.output.refresh ) {
let htmflph = self.storeStaticFilePath.htm
// 检查文件缓存
fs.readFile(htmflph, function(err, data){
if( !err ){
success(data||' ') // htm 是取自缓存
}else{
readHtmContents()
}
})
}else{
readHtmContents()
}
// htm
async function readHtmContents () {
let myHtmAry = await self.readSrcModFileContents(mysrc, 'htm')
let distHtm = parent ? parent._assemble.distHtm : ''
for (let i in myHtmAry) {
let li = myHtmAry[i]
, ik = li[1]
, con = li[2]
if(ik){
let can
, ink = '<!'+ik+'!>'
if( distHtm.indexOf(ink) > -1 ){
distHtm = distHtm.replace(ink, con+'\n'+ink) // 插入埋点
can = true
}
if( self.myHtm.indexOf(ink) > -1 ){
self.myHtm = self.myHtm.replace(ink, con+'\n'+ink) // 插入埋点
can = true
}
if( ! can ){
app.log(distHtm)
throw new Error('view tpl htm insert key '+ink+' not find !')
}
}else{
distHtm += con
self.myHtm += con
}
}
self.distHtm = distHtm
//app.log(this.myHtm)
//app.log(distHtm)
/*app.log(myCssAry)
app.log(myJsAry)
app.log(myHtmAry)*/
success()
}
})
}
// 读取模块
async readSrcModFileContents (srcs, ext) {
let self = this
let config = self.loader.realConfig
return new Promise(async function( success ){
if(!srcs || !srcs.length){
return success( [] )
}
let srcnames = [] // 纯名
let rescontents = []
for (let i in srcs) {
let spx = srcs[i].split(':')
, name = spx[0]
, insert = ''
if(spx.length>1){
insert = spx[0]
name = spx[1]
}
srcnames.push(name)
rescontents.push([name, insert, ''])
}
// 绝对路径
let files = srcnames.map(x=>{
let bs = app.path.app + '/src/' + x + '.'
return bs + ext
})
// 读取文件
await self.fsReadWithCaches(files, rescontents)
success( rescontents )
})
}
// 读取文件
async fsReadWithCaches (files, rescontents) {
let self = this
let config = self.loader.realConfig
return new Promise(function( success ){
let total = files.length
, step = 0
for (let i=0; i<total; i++) {
read(i)
}
function read( k ){
let file = files[k]
if ( !config.output.refresh){ // 是否缓存
if(srcModFileContentCache[file]) { // 取缓存
return getOne(k, srcModFileContentCache[file])
}
}
fs.readFile(file, 'utf8',function(err, data){
// app.log( 'fs.readFile : ' + file + ' = '+data )
data = data || ''
if ( !config.output.refresh){ // 是否缓存
srcModFileContentCache[file] = data
}
getOne(k, data) // 忽略错误
})
}
function getOne(k, con){
rescontents[k][2] = con // 保存
step++
if(step == total){
success( rescontents )
}
}
})
}
}
// 页面输出类
class ViewRender
{
constructor (viewer, assemble) {
this.viewer = viewer
this.assemble = assemble
}
// 输出数据
render (req, res) {
let self = this
// 取数据请求函数
let realcnf = self.viewer._loader.realConfig
, dataRequests = realcnf.request
, dataBase = util_object.clone(realcnf.data)
// 取出无依赖的先
let nodpsfunc = {}
, depsfunc = {} // 有依赖的
, funTotal = dataRequests.length // 总数
, funDone = 0 // 已完成
if (0==funTotal) {
return self.__doRenderRes(res, dataBase)
}
for ( let i in dataRequests ) {
let one = dataRequests[i]
, kn = '_$_'+i
if( one.length==1 ){
nodpsfunc[kn] = one[0]
}else if( one.length==2 ){
nodpsfunc[one[0]||kn] = one[1]
}else{
depsfunc[ one[0]||kn ] = {
func: one[1],
deps: one.slice(2),
}
}
}
// app.log( realcnf)
// app.log( dataRequests)
// 数据请求环境
let context = new app.ViewDataRequester(req, res, self.viewer)
// 开始请求数据
// app.log(nodpsfunc)
// 从无依赖的开始(必须有一个无依赖的,否则整个调用链条无法开始)
for ( let i in nodpsfunc ) {
let func = nodpsfunc[i]
callDataFunc (i, func)
}
// 调用处理函数
function callDataFunc (name, func) {
// 调用
func.call(context, function(data){
// app.log('call view data ok : '+name)
funDone++ // 完成度
dataBase[name] = data
scanFuncToCall() // 查找下一个执行
}, dataBase, name)
}
// 调用函数处理
function scanFuncToCall () {
// app.log( funDone + '/' + funTotal)
// 检查是否完成
if( funDone == funTotal ){
return self.__doRenderRes(res, dataBase) // 已完成 输出
}
// 扫描有依赖的
for (let i in depsfunc) {
let one = depsfunc[i]
// 检查依赖是否都具备
if ( isReady(i, one) ) {
depsfunc[i] = null // 踢出队列
callDataFunc(i, one.func) // 调用
}
}
}
// 是否完成依赖
function isReady (name, one) {
if ( ! one ) {
return false
}
let deps = one.deps
for (let i in deps) {
if ( ! dataBase[ deps[i] ]) {
return false
}
}
return true
}
}
/////////////////
// 输出数据
__doRenderRes (res, tpldata) {
// app.log(tpldata)
let html = this.viewer._assemble.distTplFunc( tpldata )
res.end(html)
// console.timeEnd('req-time-log')
}
}
////////////////////////////////////////////////////////////////////
// 页面类
class Viewer
{
constructor(){
this.is_init
// 文件名(loader时会写入)
this._filename
// 真实的、继承合并后的 config 对象
this._parent = null // 父级
this._loader // 加载类
this._assemble // 组装类
this._render // 输出类
}
// 配置
config () {
// 继承自(与文件名一致)
get inherit () {
return null
}
// 获取配置
get config () {
return {
// 静态替换变量
version: '',
src: [],
srcdeps: [],
output: {
file: '',
},
lib: {
css: [],
js: [],
},
static: {
// url: '',
},
replace: {
__prefix: '<%', // 默认的前缀
__suffix: '%>', // 默认的后缀
},
////////_realsrc
_realsrc: [], // 展开依赖的真实src
request: [
// data gain
],
data: {
},
}
}
/////////////////////////////
// 清理
__clean () {
// this._parent = null // 父级
// this._loader = null // 加载类
// this._assemble = null // 组装类
}
// 初始化
__init () {
let self = this
return new Promise(async function( success ){
// app.log(this._filename+'------init')
if (!self._filename) {
throw new Error('view need set this._filename !')
}
if ( self.is_init ){
return success()
}
self._loader = new ViewLoader( self )
self._assemble = new ViewAssemble( self, self._loader )
await self._assemble.handleDist() // 加载文件
self._render = new ViewRender( self, self._assemble )
// 初始化完成
self.is_init = true
// ok
success()
})
}
// 输出内容
async __render (req, res) {
// 初始化
if( ! this.is_init ){
await this.__init()
}
// 重复刷新组装模块
if (this._loader.realConfig.output.refresh) {
// app.log('handleDist refresh')
await this._assemble.handleDist()
}
// 输出内容
this._render.render(req, res)
}
}

@@ -28,2 +825,8 @@

app.Viewer = Viewer;
}
}
///

@@ -23,15 +23,26 @@ /**

// 开始加载配置等等
let app_context = await lib_loader.base();
let app = await lib_loader.base();
// 多核
let is_continue = lib_cluster.startup( app_context );
let is_continue = lib_cluster.startup( app );
if( is_continue ){
// 初始化
// 工作线程
// 启动其它服务
await lib_loader.run();
// 没有懒加载view
const cnf_is_lazy_view = app.configRead('init.view.lazyload')
if ( ! cnf_is_lazy_view ) {
// 初始化全部view页面类
await app.okgo.viewIniter.initAllView();
}
// 启动http服务
let hp = await lib_http.run( app_context );
let hp = await lib_http.run( app );
app_context.log(123);
// app.log(123);

@@ -41,3 +52,3 @@ }

// ok
resolve( app_context );
resolve( app );
});

@@ -44,0 +55,0 @@ }

@@ -11,2 +11,4 @@ /**

};
};

@@ -15,14 +15,13 @@

// 是否禁用
let not_worker = app.confRead( 'port.worker.enabled' )===false;
let use_worker = app.configRead( 'port.worker.enabled' );
if (cluster.isMaster) {
if( not_worker ){
if( use_worker ){
forkWorker(); // 创建子线程
}else{
// 主线程监听 继续
return true;
}else{
forkWorker(); // 创建子线程
return true;
}
}else{
if(not_worker){
}else{
if(use_worker){
willKill(); // 是否子线程自杀

@@ -38,13 +37,16 @@ // 子线程 继续

{
let print = `worker idx:${process.env.worker_index} pid:${process.pid} started`;
// app.log(`worker ${process.pid} started`);
// 定时自杀
let killsec = app.confRead( 'port.worker.expire' );
let killsec = parseInt( app.configRead( 'port.worker.expire' ) )
// app.log(killsec);
if( killsec > 0 ){
setTimeout(x=>{
process.exit(); //
setTimeout(function(){
// app.log(killsec+'============ kill !!!!')
process.exit(1); //
}, killsec * 1000);
print += `, after ${killsec} sec exit`;
}
app.log(print)

@@ -57,25 +59,34 @@ }

// 监听
let worker_num = app.confRead( 'port.worker.num' ) || numCPUs;
let worker_num = parseInt( app.configRead( 'port.worker.num' ) ) || numCPUs;
let http_port = app.confRead( 'port.listen.http' ) || 9693;
let http_port = app.configRead( 'port.listen.http' ) || 9693;
app.log(`expre cluster ${process.pid} listen on port ${http_port}, ${worker_num} worker starting...`);
app.log(`cluster pid:${process.pid} listen on port ${http_port}, ${worker_num} worker starting...`);
// 衍生工作进程
for (let i = 0; i < worker_num; i++) {
cluster.fork();
forkOne(i);
}
// 退出重启
let delay_time = app.confRead( 'port.worker.delay' ) || 1;
let delay_time = parseInt( app.configRead( 'port.worker.delay' ) ) || 1;
cluster.on('exit', (worker, code, signal) => {
let wkidx = worker.worker_index;
app.log(`worker ${worker.process.pid} exit, after ${delay_time} sec forking...`);
app.log(`worker idx:${wkidx} pid:${worker.process.pid} exit, after ${delay_time} sec forking...`);
setTimeout(x=>{
cluster.fork(); // 重启一个
forkOne(wkidx);
}, delay_time * 1000);
});
// fork one
function forkOne(idx){
let wkr = cluster.fork({
'worker_index': idx,
}); // 重启一个
wkr.worker_index = idx; // worker idx copy
}
}
}

@@ -25,2 +25,3 @@ /**

{
// console.time('req-time-log')

@@ -84,10 +85,34 @@ // 解析

function callCtrl(){
// app.log(route_obj.control_func)
let kind = typeof route_obj.control_func
// app.log(route_obj)
// 实例化控制器
let newController = new route_obj.control_class(req, res)
// 执行
route_obj.control_func.call( newController );
if ( kind == 'object' ) {
if ( route_obj.control_func instanceof app.StaticFileServer)
{
// static file
route_obj.control_func.__renderFileContent(req, res)
}else if (route_obj.control_func instanceof app.Viewer)
{
// view page
route_obj.control_func.__render(req, res)
}
}else if ( kind == 'function' ){
// controller
// app.log(route_obj)
// 实例化控制器
let newController = new route_obj.control_class(req, res)
// 执行
route_obj.control_func.call( newController );
}
// route_obj.control_func instanceof app.ViewDataRequester
}

@@ -94,0 +119,0 @@

@@ -24,3 +24,3 @@ /**

let cnfkey = 'port.listen.http';
let http_port = app.confRead( cnfkey );
let http_port = app.configRead( cnfkey );
if( ! http_port ){

@@ -32,3 +32,4 @@ http_port = 9693;

// 监听
let worker_num = app.confRead( 'port.worker.num' ) || numCPUs;
let worker_num = parseInt( app.configRead( 'port.worker.num' ) ) || numCPUs;
let enable_worker = app.configRead( 'port.worker.enabled' );

@@ -38,3 +39,3 @@ //if (cluster.isMaster) {

app.log(`process ${process.pid} listen port ${http_port}`);
// app.log(`process ${process.pid} listen port ${http_port}`);

@@ -53,6 +54,11 @@

if ( ! enable_worker ) {
app.log(`process pid:${process.pid} listen on port ${http_port}`);
}
});
}

@@ -26,3 +26,4 @@ /**

const util_object = require('../util/object.js')
, app = require('./app.js')
, app_mod = require('./app.js')
, app = app_mod.Context
;

@@ -48,8 +49,7 @@

await loadBoot ( ); // 引导
await loadConf ( 'conf' ); // 配置
await loadConfig ( 'config' ); // 配置
await loadCore ( ); // 核心
await loadInit ( 'init' ); // 初始化
// ok
resolve( app.Context );
resolve( app );

@@ -66,6 +66,8 @@ });

// 控制器页面等
await loadConstant ( 'constant' ); // 常量
await loadInit ( 'init' ); // 初始化
await loadLibrary ( 'library' ); // library 代码库
await loadHelp ( 'help' ); // 帮助
await loadCommon ( 'common' ); // 通用
await loadMiddleware ( 'middleware' ); // 中间件
await loadCommon ( 'common' ); // 通用
await loadModel ( 'model' ); // model 模块

@@ -77,3 +79,3 @@ await loadView ( 'view' ); // web页面

// ok
resolve( app.Context );
resolve( app );

@@ -98,6 +100,6 @@ });

, name = path.basename(f, '.js')
, router = new app.Context.Router() // 默认提供一个
, router = new app.Router() // 默认提供一个
, ret_routers = [router]
// 执行获取router
let retrts = mod(app.Context, router);
let retrts = mod(app, router);
if( retrts ){

@@ -111,7 +113,7 @@ if(retrts[0]){

for(let i in ret_routers){
ret_routers[i].__renderForContext(app.Context); // 输出至app上下文
ret_routers[i].__renderForContext(app); // 输出至app上下文
}
});
// app.Context.Log('yangjie');
// app.Log('yangjie');

@@ -133,3 +135,3 @@ // ok

app.Context[dir] = app.Context[dir] || {};
app[dir] = app[dir] || {};

@@ -140,3 +142,3 @@ // 加载执行

, name = path.basename(f, '.js')
, _class = mod(app.Context)
, _class = mod(app)
// 反射类成员函数

@@ -154,6 +156,6 @@ , ctrl_func_names = Object.getOwnPropertyNames(_class.prototype)

// 执行 实例化
app.Context[dir][name] = funcs;
app[dir][name] = funcs;
});
// console.log(app.Context[dir]);
// console.log(app[dir]);

@@ -170,14 +172,37 @@ // ok

return new Promise( async function(resolve, reject){
app[dir] = app[dir] || {};
// 扫描 js 文件,绝对路径
let files = await scanFile ( path.join(dir_app, './'+dir), 'js', true );
loadFiles(files);
// 扫描目录
let dirs = await scanDir ( path.join(dir_app, './'+dir) );
for (let i in dirs) {
let childdir = dirs[i]
let childfiles = await scanFile ( path.join(dir_app, './'+dir+'/'+childdir), 'js', true );
loadFiles(childfiles, childdir);
}
// 加载执行
files.forEach(function( f ){
let mod = require(f)
, name = path.basename(f, '.js');
// 执行
mod(app.Context);
});
// 加载 view
function loadFiles(files, basedir=''){
// 加载执行
files.forEach(function( f ){
let mod = require(f)
, name = path.basename(f, '.js');
if (basedir) {
name = basedir + '_' + name
}
if( app[dir][name] ) { // 不允许重复
throw new Error('view "'+name+'" path can\'t repeat !')
}
// 执行
let tarViewClass = mod(app);
// view 类初始化
let viewer = new tarViewClass();
viewer._filename = name; // 文件名(斜杠转下划线)
// app.log('---=======---'+name)
app[dir][name] = viewer;
});
}
// ok

@@ -197,3 +222,3 @@ resolve();

app.Context[dir] = app.Context[dir] || {};
app[dir] = app[dir] || {};

@@ -204,5 +229,5 @@ // 加载执行

, name = path.basename(f, '.js')
, modelClass = mod(app.Context)
, modelClass = mod(app)
// 执行
app.Context[dir][name] = new modelClass();
app[dir][name] = new modelClass();
});

@@ -222,3 +247,3 @@

app.Context[dir] = app.Context[dir] || {};
app[dir] = app[dir] || {};

@@ -232,3 +257,3 @@ // 扫描 js 文件,绝对路径

// 执行
app.Context[dir][name] = mod;
app[dir][name] = mod;
});

@@ -245,3 +270,3 @@

// 执行
app.Context[dir][name] = mod;
app[dir][name] = mod;
}catch(e){}

@@ -268,3 +293,3 @@ });

// 执行
mod(app.Context);
mod(app);
});

@@ -286,3 +311,3 @@

app.Context[dir] = app.Context[dir] || {};
app[dir] = app[dir] || {};

@@ -294,3 +319,3 @@ // 加载执行

// 执行
app.Context[dir][name] = mod(app.Context);
app[dir][name] = mod(app);
});

@@ -312,3 +337,3 @@

app.Context[dir] = app.Context[dir] || {};
app[dir] = app[dir] || {};

@@ -320,3 +345,3 @@ // 加载执行

// 执行
app.Context[dir][name] = mod(app.Context);
app[dir][name] = mod(app);
});

@@ -338,3 +363,3 @@

app.Context[dir] = app.Context[dir] || {};
app[dir] = app[dir] || {};

@@ -346,3 +371,3 @@ // 加载执行

// 执行
app.Context[dir][name] = mod;
app[dir][name] = mod;
});

@@ -356,4 +381,28 @@

// 加载常量
async function loadConstant( dir )
{
return new Promise( async function(resolve, reject){
// 扫描 js 文件,绝对路径
let files = await scanFile ( path.join(dir_app, './'+dir), 'js', true );
app[dir] = app[dir] || {};
// 加载执行
files.forEach(function( f ){
let mod = require(f)
, name = path.basename(f, '.js');
// 执行
app[dir][name] = mod;
});
// ok
resolve();
});
}
// 加载所有配置文件
async function loadConf ( dir )
async function loadConfig ( dir )
{

@@ -377,3 +426,3 @@ return new Promise( async function(resolve, reject){

app.Context[dir] = app.Context[dir] || {};
app[dir] = app[dir] || {};

@@ -385,3 +434,3 @@ // 加载配置

// 数据get
app.Context[dir][name] = mod(app.Context);
app[dir][name] = mod(app);
});

@@ -395,4 +444,4 @@

util_object.extend(
( app.Context[dir][name] || {}),
mod(app.Context),
( app[dir][name] || {}),
mod(app),
true // 覆盖

@@ -420,3 +469,3 @@ );

// 执行
mod(app.Context);
mod(app);
});

@@ -443,3 +492,3 @@

// 执行
mod(app.Context);
mod(app);
});

@@ -446,0 +495,0 @@

@@ -7,6 +7,32 @@ /**

var path = require('path');
var exec = require('child_process').exec
//递归创建目录 异步方法
var mkdirs = exports.mkdirs = function (dirname, callback=()=>{}) {
fs.exists(dirname, function (exists) {
if (exists) {
callback();
} else {
//console.log(path.dirname(dirname));
mkdirs(path.dirname(dirname), function () {
fs.mkdir(dirname, callback);
});
}
});
}
// 【小心使用】 限 linux
// 强制删除文件夹
exports.deleteFolderForce = function ( abs_dir ) {
exec('rm -rf '+abs_dir,function(err,out) {
// console.log(out); err && console.log(err);
});
}
/**

@@ -20,3 +46,6 @@ * 按文件名数组读取文件并按顺序合并,异步版本

{
opts = opts || {};
opts = opts || {
merge: false, // 合并
ext: null, // 文件后缀名
};

@@ -23,0 +52,0 @@ var leg = nameAry.length

@@ -13,8 +13,10 @@

for(var i in get){
if(get[i] instanceof Object){
if(get[i] instanceof Array){
if(override || !tar[i]){
tar[i] = get[i];
}
}else if(get[i] instanceof Object){
tar[i] = tar[i] || {};
exports.extend(tar[i],get[i],override);
}else if(get[i] instanceof Array){
if(override || !tar[i])
tar[i] = get[i];
}else{

@@ -21,0 +23,0 @@ if(override || !tar[i])

@@ -62,6 +62,7 @@ /**

*/
exports.replaceAll = function(str, s1, s2){
return str.replace(new RegExp(s1,"gm"),s2);
exports.replaceAll = function(str, s1, s2){
return str.split(s1).join(s2);
// return str.replace(new RegExp(s1,"gm"),s2);
}
{
"name": "okgo",
"version": "0.0.3",
"version": "0.0.4",
"description": "enterprise-level high-performance web app framework",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc