import path from 'path'
import fs from 'fs'
import get from 'lodash-es/get.js'
import debounce from 'lodash-es/debounce.js'
import merge from 'lodash-es/merge.js'
import now2str from 'wsemi/src/now2str.mjs'
import genID from 'wsemi/src/genID.mjs'
import evem from 'wsemi/src/evem.mjs'
import isestr from 'wsemi/src/isestr.mjs'
import iseobj from 'wsemi/src/iseobj.mjs'
import j2o from 'wsemi/src/j2o.mjs'
import o2j from 'wsemi/src/o2j.mjs'
let fdSrv = path.resolve()
/**
* 伺服器端之資料同步器
*
* @class
* @param {Object} [opt={}] 輸入設定物件,預設{}
* @param {Integer} [opt.fnTableTags='tableTags.json'] 輸入各資料表時間戳儲存檔案名稱字串,預設'tableTags.json'
* @returns {Object} 回傳後端資料同步物件,可監聽事件changeTableTags、error,可使用函數readTableTags、writeTableTags、initTableTags、setTableTags、getTableTags、updateTableTag
* @example
*/
function WSyncWebdataServer(opt = {}) {
let nowTableTags = {}
//fnTableTags
let fnTableTags = get(opt, 'fnTableTags')
if (!isestr(fnTableTags)) {
fnTableTags = 'tableTags.json'
}
fnTableTags = `${fdSrv}/${fnTableTags}`
//ee
let ee = evem()
//eeEmit
function eeEmit(name, ...args) {
setTimeout(() => {
ee.emit(name, ...args)
}, 1)
}
/**
* 讀取各資料表時間資料
*
* @memberof WSyncWebdataServer
* @returns {Object} 回傳各資料表時間戳物件
* @example
* let tableTags = wsds.readTableTags()
*/
function readTableTags() {
let r = {}
try {
if (fs.existsSync(fnTableTags)) {
let c = fs.readFileSync(fnTableTags, 'utf8')
let o = j2o(c)
if (iseobj(o)) {
r = o
}
}
}
catch (err) {
eeEmit('error', {
msg: 'readTableTags catch',
err,
})
}
return r
}
/**
* 儲存各資料表時間資料
*
* @memberof WSyncWebdataServer
* @param {Object} tableTags 輸入各資料表時間戳物件
* @returns {Undefined} 無回傳
* @example
* let tableTags = {...}
* wsds.writeTableTags(tableTags)
*/
function writeTableTags() {
try {
let c = o2j(nowTableTags)
fs.writeFileSync(fnTableTags, c, 'utf8')
}
catch (err) {
eeEmit('error', {
msg: 'writeTableTags catch',
err,
})
}
}
/**
* 初始化各資料表時間資料
*
* @memberof WSyncWebdataServer
* @param {Object} tableTags 輸入各資料表時間戳物件
* @param {String} [mode='useInputFirst'] 輸入使用設定方式字串,可有'useInputFirst'代表使用傳入設定優先再與既有JSON檔設定合併,為預設值,'useStorageFirst'代表使用既有JSON檔設定優先再與傳入設定合併,'useInputOnly'代表只使用傳入設定,'useStorageOnly'代表只使用既有JSON檔設定
* @returns {Undefined} 無回傳
* @example
* let tableTags = {...}
* let mode = ''
* wsds.initTableTags(tableTags, mode)
*/
function initTableTags(tableTags = {}, mode = 'useInputFirst') {
// mode可有:
// useInputFirst
// useStorageFirst
// useInputOnly
// useStorageOnly
//mode
if (mode === 'useStorageFirst') {
nowTableTags = merge(tableTags, readTableTags())
}
else if (mode === 'useInputOnly') {
nowTableTags = tableTags
}
else if (mode === 'useStorageOnly') {
nowTableTags = readTableTags()
}
else {
//mode === 'useInputFirst'
nowTableTags = merge(readTableTags(), tableTags)
}
//writeTableTags
writeTableTags()
}
/**
* 直接設定各資料表時間資料
*
* @memberof WSyncWebdataServer
* @param {Object} tableTags 輸入各資料表時間戳物件
* @returns {Undefined} 無回傳
* @example
* let tableTags = {...}
* wsds.setTableTags(tableTags)
*/
function setTableTags(tableTags = {}) {
//merge
nowTableTags = merge(nowTableTags, tableTags)
//writeTableTags
writeTableTags()
}
/**
* 直接取得各資料表時間資料
*
* @memberof WSyncWebdataServer
* @returns {Object} 回傳各資料表時間戳物件
* @example
* let tableTags = wsds.getTableTags()
*/
function getTableTags() {
return nowTableTags
}
//updateTableTagCore, 避免大量更新時造成大量推播, 通過debounce合併故是回傳nowTableTags
let updateTableTagCore = debounce(() => {
//writeTableTags
writeTableTags()
//emit
eeEmit('changeTableTags', nowTableTags)
}, 200)
/**
* 更新指定資料表之時間戳,當資料表更新時需調用此函數
*
* @memberof WSyncWebdataServer
* @param {String} tableTag 輸入欲更新指定資料表名稱字串
* @returns {Undefined} 無回傳
* @example
* let tableName = '...'
* wsds.updateTableTag(tableName)
*/
function updateTableTag(tableName) {
//modify
nowTableTags[tableName] = now2str() + '|' + genID(6)
//updateTableTagCore
updateTableTagCore()
}
/**
* 監聽更新資料表事件,當外部監聽收到更新通知時再推播nowTableTags至前端
*
* @memberof WSyncWebdataServer
* @param {Object} nowTableTags 各資料表時間戳物件
* @example
* wo.on('changeTableTags', function(nowTableTags) {
* ...
* })
*/
function onChangeUpdateTableTag() {} onChangeUpdateTableTag()
ee.readTableTags = readTableTags
ee.writeTableTags = writeTableTags
ee.initTableTags = initTableTags
ee.setTableTags = setTableTags
ee.getTableTags = getTableTags
ee.updateTableTag = updateTableTag
return ee
}
export default WSyncWebdataServer