import { ConversationState , TurnContext , Promiseable } from 'botbuilder' ; import botbuilderReduxMiddleware , { getStore as getReduxStore } from 'botbuilder-redux/dist' ; import { Middleware , Store , createStore , applyMiddleware , compose as composeFunc } from 'redux' ; import rootReducer from '../reducers' ; import { NlpResult , Ability , ConvoState , WolfState , IncomingSlotData , SetSlotDataFunctions } from '../types' ; import intake from '../stages/intake' ; import fillSlot from '../stages/fillSlot' ; import evaluate from '../stages/evaluate' ; import execute from '../stages/execute' ; import outtake , { OuttakeResult } from '../stages/outtake' ; import { fillSlot as fillSlotAction , enableSlot , disableSlot , setSlotDone , addSlotToOnFillStack } from '../actions' ; const userMessageDataKey = Symbol ( 'userMessageDataKey' ) ; const wolfMessagesKey = Symbol ( 'wolfMessageKey' ) ; param middlewares param compose export const createWolfStore = ( middlewares ? , compose ? ) => ( wolfStateFromConvoState ) => { if ( typeof middlewares === 'undefined' ) { middlewares = [ ] ; } if ( typeof compose === 'undefined' ) { compose = composeFunc ; } const defaultWolfState = { messageData : null , slotStatus : [ ] , slotData : [ ] , abilityStatus : [ ] , promptedSlotStack : [ ] , focusedAbility : null , outputMessageQueue : [ ] , filledSlotsOnCurrentTurn : [ ] , abilitiesCompleteOnCurrentTurn : [ ] , defaultAbility : null , runOnFillStack : [ ] } ; const state = wolfStateFromConvoState || defaultWolfState ; return createStore ( rootReducer , state , compose ( applyMiddleware ( ... middlewares ) ) ) ; } ; return export default function initializeWolfStoreMiddleware ( conversationStore , userMessageData , getAbilitiesFunc , defaultAbility , storeCreator , getSlotDataFunc ? ) { return [ botbuilderReduxMiddleware ( conversationStore , storeCreator , '__WOLF_STORE__' ) , { onTurn : async ( context , next ) => { if ( context . activity . type !== 'message' ) { await next ( ) ; } else { const store = getStore ( context ) ; const nlpResult = await userMessageData ( context ) ; const abilities = await getAbilitiesFunc ( context ) ; const convoState = conversationStore . get ( context ) || { } ; const incomingSlotData = getSlotDataFunc ? await getSlotDataFunc ( context , { setSlotValue : ( abilityName , slotName , value ) => { store . dispatch ( fillSlotAction ( slotName , abilityName , value ) ) ; } , setSlotEnabled : ( abilityName , slotName , enable ) => { if ( enable ) { store . dispatch ( enableSlot ( { abilityName , slotName } ) ) ; return ; } store . dispatch ( disableSlot ( { abilityName , slotName } ) ) ; } , setSlotDone : ( abilityName , slotName , done ) => { store . dispatch ( setSlotDone ( { abilityName , slotName } , done ) ) ; } , fulfillSlot : ( abilityName , slotName , value ) => { store . dispatch ( addSlotToOnFillStack ( { slotName , abilityName } , value ) ) ; } } ) : [ ] ; intake ( store , nlpResult , incomingSlotData , defaultAbility ) ; fillSlot ( store , convoState , abilities ) ; evaluate ( store , abilities , convoState ) ; const executeResult = execute ( store , convoState , abilities ) ; if ( executeResult ) { const { runOnComplete , addMessage } = executeResult ; const messages = await runOnComplete ( ) ; messages . forEach ( addMessage ) ; } const messagesObj = outtake ( store ) ; context . services . set ( wolfMessagesKey , messagesObj ) ; await next ( ) ; } } } ] ; } export function getStore ( context ) { return getReduxStore ( context , '__WOLF_STORE__' ) ; } export function getMessages ( context ) { return context . services . get ( wolfMessagesKey ) ; }