UNPKG

@onereach/step-voice

Version:
167 lines (166 loc) 5.83 kB
"use strict"; /* eslint-disable @typescript-eslint/strict-boolean-expressions */ Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const step_1 = tslib_1.__importDefault(require("@onereach/flow-sdk/dst/step")); class ConvStep extends step_1.default { get cache() { return this.convDataCache; } get conversation() { if (this.data.conversation == null) throw new Error('missing data.conversation'); return this.data.conversation; } get conversationId() { const convOrName = this.conversation; const conv = (typeof convOrName === 'string') ? this.config.mergeFields[convOrName] ?? convOrName : convOrName; if (conv.type === 'thread') return this.dataThreadId; if (typeof conv.name === 'string') return conv.name; if (typeof convOrName === 'string') return convOrName; throw new Error(`invalid conversation ${JSON.stringify(conv)}`); } get workerThreadId() { return `G:${this.conversationId}`; } /** id of the thread where conversation data is stored */ get dataThreadId() { const dataThreadId = this.state.thread ?? this.data.conversationThread; return dataThreadId || this.thread.id; } get isGlobal() { return false; } get isWorker() { return this.thread.id === this.workerThreadId; } get useQueue() { return true; } async fetchData() { const data = await this._fetchCache(); if (data?._conv == null) throw new Error(`missing conversation data in state ${this.state.name}`); return data; } async getConversation() { return (await this.fetchData())._conv; } async updateData() { if (this.convDataCache == null) throw new Error(`missing conversation cache in state ${this.state.name}`); // console.log('UPDATE', this.conversation, this.thread.id, this.step.label, this.convDataCache?._conv.que) const convDataThread = this.process.getSafeThread(this.dataThreadId); await convDataThread.set(this.conversation, this.convDataCache); } async hasConversation() { return (await this._fetchCache())?._conv != null; } async runBefore() { await super.runBefore(); this.log.debug('conv.runBefore', { state: this.state, conv: this.convDataCache?._conv }); if (this.thread.ending) return; // ensure cache is reset between step runs, just in case this._clearCache(); if (!await this.hasConversation()) return; if (this.state.direct) return; if (!this.event.processed && this.event.action && typeof this[this.event.action] === 'function') { this.event.processed = true; this.state.prevName = this.state.name; this.state.name = this.event.action; } } async onSkipEvent() { this.log.debug('onSkipEvent'); this.state.name = this.state.prevSkipName; delete this.state.prevSkipName; } async cancel() { if (this.isGlobal) { this.log.debug('conv.cannot cancel global'); } } async onCancel() { // await this.popConvStep() if (this.getExitStepId('cancel')) { this.log.debug('conv.cancel exit'); this.exitStep('cancel'); } else { return await this.waitConvEnd(); } } async onSleep() { // sleep } async onAwake() { this.state.name = this.state.resumeState; this.state.resumeState = undefined; } async onPause() { this.state.resumeState = this.state.prevName; this.state.prevName = undefined; } async onResume() { this.state.name = this.state.resumeState; this.state.resumeState = undefined; } async waitConvEnd() { const workerThread = this.process.getThread(this.workerThreadId); const workerState = workerThread?.state; if (!this.isGlobal && this.thread.id !== 'main' && this.thread.id === workerState?.thread) { this.log.debug('conv.wait for end', this.conversation); this.gotoState({ ...this.state, name: this.waitGlobEnd.name, direct: true }); } else { this.log.debug('conv.end', this.conversation); await this.onConvEnd(); } } async waitGlobEnd() { const gcThreadId = this.workerThreadId; // wait for glob thread end (if exists) this.triggers.hook({ name: "end" /* ACTION.end */, thread: gcThreadId, times: 1 }, async () => await this.onConvEnd()); if (!this.process.getThread(gcThreadId)) await this.onConvEnd(); } async onConvEnd() { this.end(); } async pause() { } async resume() { } async startConversation(data, { thread: _thread } = {}) { this.convDataCache = { ...data, _conv: data._conv ?? {} }; await this.updateData(); // this.state.thread = this.dataThreadId } async _fetchCache() { if (this.convDataCache != null) return this.convDataCache; const convDataThread = this.process.getSafeThread(this.dataThreadId); this.convDataCache = await convDataThread.get(this.conversation); // console.log('FETCH', this.conversation, this.thread.id, this.step.label, this.convDataCache?._conv.que) return this.convDataCache; } _clearCache() { this.convDataCache = undefined; } async _refreshCache() { this._clearCache(); await this._fetchCache(); } } exports.default = ConvStep;