asksuite-core
Version:
262 lines (224 loc) • 7.85 kB
JavaScript
const promisesTranslateTree = {};
const thenPromisesTranslateTree = {};
const _ = require('lodash');
const PromiseBlue = require('bluebird');
const { AsksuiteTreeManagerGeneralUtils } = require('./asksuite.tree.manager.general.utils');
class AsksuiteTreeManagerGeneral {
constructor({
configuration,
CompanyMap,
TreeMap,
IntentsMap,
AsksuiteUtil,
AsksuiteService,
InitMap,
treesTestingCache,
getLanguages,
translator,
wait,
}) {
this.configuration = configuration;
this.CompanyMap = CompanyMap;
this.TreeMap = TreeMap;
this.getLanguages = getLanguages;
this.IntentsMap = IntentsMap;
this.AsksuiteUtil = AsksuiteUtil;
this.translator = translator;
this.AsksuiteService = AsksuiteService;
this.treesTestingCache = treesTestingCache;
this.InitMap = InitMap;
this.wait = wait;
}
getLanguagesByCompany(chatTreeId) {
const company =
this.CompanyMap.get(chatTreeId) || this.CompanyMap.get(chatTreeId.split('.')[1]);
return AsksuiteTreeManagerGeneralUtils.getLanguagesByCompany(company);
}
resolveDefaultLanguage(languages, language) {
return AsksuiteTreeManagerGeneralUtils.resolveDefaultLanguage(languages, language);
}
resolveLanguage(paramLanguage, companyId) {
let languages = this.getLanguages();
companyId = companyId || '';
const company = this.CompanyMap.get(companyId) || this.CompanyMap.get(companyId.split('.')[1]);
if (company && !_.isEmpty(company.languages)) {
languages = _.filter(languages, l => _.includes(company.languages, l.formatIso));
}
return this.AsksuiteUtil.resolveLanguage(paramLanguage, languages);
}
flushTreeMapKeys(keys) {
const languages = this.getLanguages();
if (keys && Array.isArray(keys)) {
languages.forEach(({ formatIso }) => {
keys.forEach(key => {
const treeInstance = this.resolveTreeInstance(formatIso);
if (treeInstance.has(key)) {
treeInstance.delete(key);
}
});
});
}
}
resolveTreeInstance(language, companyId) {
language = this.resolveLanguage(language, companyId);
if (!this.TreeMap.has(language)) {
this.TreeMap.set(language, new Map());
}
return this.TreeMap.get(language);
}
isTreeAlreadyRegistred(chatTreeId, paramLanguage) {
const company =
this.CompanyMap.get(chatTreeId) || this.CompanyMap.get(chatTreeId.split('.')[1]);
if (!paramLanguage && company) {
return this.resolveTreeInstance(company.defaultLanguage, chatTreeId).has(chatTreeId);
}
return this.resolveTreeInstance(paramLanguage, chatTreeId).has(chatTreeId);
}
async recursiveDialog(map, node) {
if (node.children) {
node.children.forEach(async item => {
map.set(item.dialog, item);
await this.recursiveDialog(map, item);
});
}
}
async initTreeMap(map, tree) {
map.set(tree.json.dialog, tree.json);
await this.recursiveDialog(map, tree.json);
}
async initTreeByLanguage(language, languageFrom, tree, needTranslate, languages) {
const treeInstance = this.resolveTreeInstance(language, tree.chatTreeId);
return new Promise((resolve, reject) => {
(async () => {
if (needTranslate) {
console.time(`${tree.chatTreeId}: ${languageFrom} -> ${language}`);
const cached = await AsksuiteTreeManagerGeneralUtils.getCachedChatTree(
this.configuration,
tree.chatTreeId,
language,
);
if (cached) {
tree = cached;
console.log(`Cached tree ${tree.chatTreeId} -- ${language}`);
} else {
tree = await this.translator
.translate(tree, language, languageFrom, languages)
.catch(reject);
}
console.timeEnd(`${tree.chatTreeId}: ${languageFrom} -> ${language}`);
}
await this.initTreeMap(treeInstance, tree).catch(reject);
resolve();
})();
});
}
async initTreesByCompanyIDIfNeeded(idsTrees, paramLanguage) {
return Promise.all(
_.map(idsTrees, async idTree => {
const language = this.resolveLanguage(paramLanguage, idTree);
if (!this.isTreeAlreadyRegistred(idTree, language)) {
await this.initTreeByCompanyID(idTree, language);
}
}),
);
}
async initTreeByCompanyID(idTree, paramLanguage) {
const language = this.resolveLanguage(paramLanguage, idTree);
let key = `${idTree}`;
if (language) {
key += `-${language}`;
}
if (!this.InitMap.get(idTree) && !(language && this.InitMap.get(key))) {
this.InitMap.set(key, true);
let tree;
if (this.treesTestingCache && this.treesTestingCache.get(idTree)) {
tree = this.treesTestingCache.get(idTree);
} else {
tree = await this.AsksuiteService.findTreeByCompanyId(idTree);
}
const result = await this.initTree(tree, language).catch(e => {
return { error: true, e };
});
this.InitMap.delete(key);
if (result && result.error) {
throw result.e;
}
} else {
await this.wait.until(function() {
return !this.InitMap.get(idTree) && !(language && this.InitMap.get(key));
});
}
}
resolveThenInitTree(chatTreeId) {
const { tree, language } = thenPromisesTranslateTree[chatTreeId];
console.log('--------------------------------------- resolveThenInitTree', {
chatTreeId,
language,
});
delete thenPromisesTranslateTree[chatTreeId];
return this.initTree(tree, language);
}
async initTree(tree, language) {
if (promisesTranslateTree[tree.chatTreeId]) {
//next initTree
const itemInQueue = thenPromisesTranslateTree[tree.chatTreeId];
const promise = promisesTranslateTree[tree.chatTreeId].catch(e =>
console.log('error initTree', e),
);
if (itemInQueue) {
if (itemInQueue.language && itemInQueue.language !== language) {
itemInQueue.language = null;
}
itemInQueue.tree = tree;
} else {
thenPromisesTranslateTree[tree.chatTreeId] = { tree, language };
return promise.then(() => this.resolveThenInitTree(tree.chatTreeId));
}
return promise;
}
promisesTranslateTree[tree.chatTreeId] = new Promise(resolve => {
(async () => {
console.log('init initTree', tree.chatTreeId);
this.IntentsMap.set(tree.chatTreeId, tree.intents);
let languages = this.getLanguagesByCompany(tree.chatTreeId);
const defaultLanguage = this.resolveDefaultLanguage(languages, tree.defaultLanguage);
if (language) {
const lang = this.resolveDefaultLanguage(languages, language);
languages = _.filter(languages, l => l === lang);
if (
!this.isTreeAlreadyRegistred(tree.chatTreeId, defaultLanguage) &&
!_.includes(languages, defaultLanguage)
) {
languages.push(defaultLanguage);
}
}
const allLanguages = this.getLanguages();
try {
await PromiseBlue.map(
languages,
lang => {
return this.initTreeByLanguage(
lang,
defaultLanguage,
tree,
lang !== defaultLanguage,
allLanguages,
);
},
{ concurrency: 1 },
);
} catch (e) {
console.log('error on initTree', e);
} finally {
console.log('end initTree', tree.chatTreeId);
resolve();
delete promisesTranslateTree[tree.chatTreeId];
}
})();
});
return promisesTranslateTree[tree.chatTreeId];
}
}
module.exports = {
AsksuiteTreeManagerGeneral,
};