botpress
Version:
The world's first CMS for bots. Easily create, manage and extend chatbots.
168 lines (138 loc) • 8.4 kB
JavaScript
;
var _helpers = require('../database/helpers');
var _helpers2 = _interopRequireDefault(_helpers);
var _lodash = require('lodash');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /**
* The Dialog State Manager is in charge of keeping track of the state
* for all conversations. This is being used internally by the [Dialog Engine]{@link DialogEngine}
* but is also exposed publicly if you need to programmatically alter the state of some conversations.
* @namespace DialogStateManager
* @example
* bp.dialogEngine.stateManager
*/
module.exports = ({ db }) => {
const isExpired = session => {
return false; // TODO Implement
};
const _upsertState = (() => {
var _ref = _asyncToGenerator(function* (stateId, state) {
const knex = yield db.get();
const h = (0, _helpers2.default)(knex);
const params = {
tableName: 'dialog_sessions',
stateId,
state: JSON.stringify(state),
now: h.date.now()
};
const sql = h.isLite() ? `
INSERT OR REPLACE INTO :tableName: (id, state, active_on)
VALUES (:stateId, :state, :now)
` : `
INSERT INTO :tableName: (id, state, active_on, created_on)
VALUES (:stateId, :state, :now, :now)
ON CONFLICT (id) DO UPDATE
SET active_on = :now, state = :state
`;
return knex.raw(sql, params);
});
return function _upsertState(_x, _x2) {
return _ref.apply(this, arguments);
};
})();
const _createEmptyState = stateId => ({ _stateId: stateId });
const _createSession = (() => {
var _ref2 = _asyncToGenerator(function* (stateId) {
const knex = yield db.get();
const h = (0, _helpers2.default)(knex);
const state = _createEmptyState(stateId);
const params = {
tableName: 'dialog_sessions',
stateId,
state: JSON.stringify(state),
now: h.date.now()
};
const sql = h.isLite() ? `
INSERT OR REPLACE INTO :tableName: (id, state, active_on, created_on)
VALUES (:stateId, :state, :now, :now)
` : `
INSERT INTO :tableName: (id, state, active_on, created_on)
VALUES (:stateId, :state, :now, :now)
ON CONFLICT (id) DO UPDATE
SET created_on = :now, active_on = :now, state = :state
`;
yield knex.raw(sql, params);
return state;
});
return function _createSession(_x3) {
return _ref2.apply(this, arguments);
};
})();
/**
* Returns the current state of the conversation
* @param {String} stateId
* @return {Object} The conversation state
* @async
* @memberof! DialogStateManager
* @example
* const state = await bp.dialogEngine.stateManager.getState(event.user.id)
*/
const getState = (() => {
var _ref3 = _asyncToGenerator(function* (stateId) {
const knex = yield db.get();
const session = yield knex('dialog_sessions').where({ id: stateId }).limit(1).then().get(0);
if (session) {
if (isExpired(session)) {
// TODO trigger time out
return _createSession(stateId);
} else {
return JSON.parse(session.state);
}
} else {
return _createSession(stateId);
}
});
return function getState(_x4) {
return _ref3.apply(this, arguments);
};
})();
/**
* Overwrites the state of a current conversation
* @param {String} stateId
* @param {Object} state The conversation state
* @return {Object} The new state
* @async
* @memberof! DialogStateManager
*/
const setState = (stateId, state) => {
if (state != null && !(0, _lodash.isPlainObject)(state)) {
throw new Error('State must be a plain object');
}
return _upsertState(stateId, state != null ? state : _createEmptyState(stateId));
};
/**
* Deletes the state(s) and (optionally) the associated sub-states (for e.g. ___context sub-state)
* @param stateId The state to delete
* @param {Array<String>} [substates] Detaults to ['context']. If this is empty it will delete no substate
* @async
* @memberof! DialogStateManager
*/
const deleteState = (() => {
var _ref4 = _asyncToGenerator(function* (stateId, substates = ['context']) {
const knex = yield db.get();
const states = [stateId, ...substates.map(function (x) {
return `${stateId}___${x}`;
})];
yield knex('dialog_sessions').whereIn('id', states).del().then();
});
return function deleteState(_x5) {
return _ref4.apply(this, arguments);
};
})();
return {
getState,
setState,
deleteState
};
};
//# sourceMappingURL=state.js.map