wa-chat-server
Version:
Watson Assistant powered chat server
142 lines (141 loc) • 6.38 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Session = void 0;
const ISessionConfig_1 = require("../../interface/ISessionConfig");
const SessionDoesNotExistError_1 = require("../../exception/SessionDoesNotExistError");
const SessionExpiredError_1 = require("../../exception/SessionExpiredError");
const SessionStorageFactoryProcessMemory_1 = require("./SessionStorageFactoryProcessMemory");
/**
* Session implementation
*
* Usage:
* const session = await new Session(sessionId, ...).start();
* 1) session.data.general[KEY] = VALUE;
* 2) session.data.assistants[ALIAS][KEY] = VALUE;
* await session.save()
*
* If we don't have sessionId we just provide empty value and
* a new session will be created. Similarly a new session is created
* if the provided session id does not correspond to a valid session.
* The session id effectively used is stored in the public class
* property sessionId.
*/
class Session {
constructor(sessionId, config = {}, storageFactories = new Map([[ISessionConfig_1.SessionType.ProcessMemory, new SessionStorageFactoryProcessMemory_1.SessionStorageFactoryProcessMemory()]])) {
this.sessionId = sessionId;
this.config = config;
this.storageFactories = storageFactories;
this.data = {
general: {
shared: {},
runningAssistant: '',
},
assistants: {},
history: [],
};
this.sessionStorage = null;
this.config.storageName = this.config.storageName || ISessionConfig_1.SessionType.ProcessMemory;
if (!this.storageFactories.has(this.config.storageName)) {
throw new Error(`storageName "${this.config.storageName}" was not be found in storageFactories`);
}
}
initStorage() {
return __awaiter(this, void 0, void 0, function* () {
const { storageName, singleUseStorage, lifeTimeMS, allowForeignSessionIds } = this.config;
const factory = this.storageFactories.get(storageName);
const { singleUseStorageOnly } = factory.config;
const useShared = !singleUseStorageOnly && !singleUseStorage;
if (useShared) {
if (!Session.sessionStorages.has(storageName)) {
// cannot override config in shared storage
const sessionStorage = factory.createStorage();
yield sessionStorage.init();
Session.sessionStorages.set(storageName, sessionStorage);
}
this.sessionStorage = Session.sessionStorages.get(storageName);
}
else {
const singleUseStorageConfig = {
lifeTimeMS: lifeTimeMS,
allowForeignSessionIds: allowForeignSessionIds,
};
this.sessionStorage = factory.createStorage(singleUseStorageConfig);
yield this.sessionStorage.init();
}
});
}
restartSession() {
return __awaiter(this, void 0, void 0, function* () {
this.sessionId = this.config.allowForeignSessionIds
? yield this.sessionStorage.create(this.sessionId)
: yield this.sessionStorage.create();
this.initSessionData();
this.save();
});
}
initSessionData() {
this.data.general = {
shared: {},
runningAssistant: 'MASTER',
};
this.data.assistants = this.data.assistants || {};
this.data.assistants.MASTER = { context: {} };
this.runningAssistant = 'MASTER';
}
start() {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b;
try {
yield this.initStorage();
this.data = yield this.sessionStorage.read(this.sessionId);
if ((_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a.general) === null || _b === void 0 ? void 0 : _b.runningAssistant) {
this.runningAssistant = this.data.general.runningAssistant;
}
else {
this.initSessionData();
}
}
catch (e) {
if (e instanceof SessionDoesNotExistError_1.SessionDoesNotExistError || e instanceof SessionExpiredError_1.SessionExpiredError) {
yield this.restartSession();
}
else {
throw e;
}
}
return this;
});
}
updateContext(newPayload) {
var _a;
this.data.assistants[this.runningAssistant] = this.data.assistants[this.runningAssistant] || {};
this.data.assistants[this.runningAssistant].context = Object.assign(Object.assign({}, (((_a = this.data.assistants[this.runningAssistant]) === null || _a === void 0 ? void 0 : _a.context) || {})), ((newPayload === null || newPayload === void 0 ? void 0 : newPayload.result.context) || {}));
}
save() {
return __awaiter(this, void 0, void 0, function* () {
this.data.general.runningAssistant = this.runningAssistant;
yield this.sessionStorage.write(this.sessionId, this.data);
});
}
getStorage() {
return this.sessionStorage;
}
currentData() {
return this.data.assistants[this.runningAssistant] || {};
}
setRunningAssistant(runningAssistant) {
this.runningAssistant = runningAssistant;
this.data.general.runningAssistant = runningAssistant;
}
}
exports.Session = Session;
Session.sessionStorages = new Map();