Skip to content

Store API

The chat store manages all chat state and provides methods for interaction. It's built with Pinia and provides reactive state management.

Import

typescript
import { useChatStore } from '@sprout_lbjocson/sprout-sidekick'

Usage

The useChatStore() function accepts optional configuration options. When used within components, it automatically receives the plugin options via Vue's inject system. For standalone usage, you can pass options directly:

typescript
// Within a component (automatically gets plugin options)
import { inject } from 'vue'
import { useChatStore } from '@sprout_lbjocson/sprout-sidekick'
import type { SidekickChatOptions } from '@sprout_lbjocson/sprout-sidekick'

const pluginOptions = inject<SidekickChatOptions>('sidekickChatOptions', {})
const chatStore = useChatStore(pluginOptions)

// Standalone usage
const chatStore = useChatStore({
  mode: 'PROD',
  baseUrl: 'https://custom-backend.com',
})

Note: The store uses the provided options to determine which backend endpoint to use (based on mode or baseUrl configuration).

State

messages

  • Type: Ref<ChatMessage[]>
  • Description: Array of all chat messages
  • Reactive: Yes
typescript
const messages = chatStore.messages
// or
const messages = computed(() => chatStore.messages)

isTyping

  • Type: Ref<boolean>
  • Description: Indicates if the bot is currently typing
  • Reactive: Yes

isConnected

  • Type: Ref<boolean>
  • Description: Indicates if the chat is connected
  • Reactive: Yes

token

  • Type: Ref<string | null>
  • Description: Authentication token
  • Reactive: Yes

isOpen

  • Type: Ref<boolean>
  • Description: Indicates if the chat widget is open (for SidekickChatPlugin)
  • Reactive: Yes

Getters

messageCount

  • Type: ComputedRef<number>
  • Description: Total number of messages
  • Returns: Number of messages in the chat
typescript
const count = chatStore.messageCount

lastMessage

  • Type: ComputedRef<ChatMessage | undefined>
  • Description: The most recent message
  • Returns: Last message object or undefined if no messages
typescript
const lastMsg = chatStore.lastMessage

isAuthenticated

  • Type: ComputedRef<boolean>
  • Description: Whether user is authenticated (has a valid token)
  • Returns: True if token exists
typescript
const isAuth = chatStore.isAuthenticated

Actions

Authentication

setToken(newToken: string)

Sets the authentication token and marks the connection as active.

typescript
chatStore.setToken('your-auth-token-here')

Parameters:

  • newToken (string): The authentication token

Side Effects:

  • Sets isConnected to true

clearToken()

Clears the authentication token and disconnects.

typescript
chatStore.clearToken()

Side Effects:

  • Sets isConnected to false
  • Sets token to null

Message Management

addMessage(text: string, sender?: 'user' | 'bot')

Adds a new message to the chat.

typescript
// Add user message
chatStore.addMessage('Hello!', 'user')

// Add bot message
chatStore.addMessage('Hi there!', 'bot')

// Default is 'user'
chatStore.addMessage('Default user message')

Parameters:

  • text (string): The message text
  • sender ('user' | 'bot', optional): Message sender, defaults to 'user'

Returns: void

clearMessages()

Removes all messages from the chat locally.

typescript
chatStore.clearMessages()

clearSession()

Clears the chat session both locally and on the server. This will call the clear_chat API endpoint and then clear local messages.

typescript
try {
  await chatStore.clearSession()
} catch (error) {
  console.error('Failed to clear session:', error)
  // Local messages are still cleared even if API call fails
}

Returns: Promise<void>

Throws: Error if not authenticated or API call fails

Behavior:

  1. Calls the clear_chat API endpoint with user credentials
  2. Clears local messages after successful API call
  3. If API call fails, still clears local messages as fallback

sendMessage(text: string)

Sends a user message and triggers a bot response.

typescript
try {
  await chatStore.sendMessage('How can you help me?')
} catch (error) {
  console.error('Failed to send message:', error)
}

Parameters:

  • text (string): The message text to send

Returns: Promise<void>

Throws: Error if not authenticated

Behavior:

  1. Adds user message
  2. Sets isTyping to true
  3. Simulates API delay (1-2 seconds)
  4. Sets isTyping to false
  5. Adds bot response message

Chat State Management

setTyping(typing: boolean)

Sets the typing indicator state.

typescript
chatStore.setTyping(true) // Show typing indicator
chatStore.setTyping(false) // Hide typing indicator

toggleChat()

Toggles the chat widget open/closed state.

typescript
chatStore.toggleChat()

openChat()

Opens the chat widget.

typescript
chatStore.openChat()

closeChat()

Closes the chat widget.

typescript
chatStore.closeChat()

Types

ChatMessage

typescript
interface ChatMessage {
  id: string
  text: string
  sender: 'user' | 'bot'
  timestamp: Date
}

ChatState

typescript
interface ChatState {
  messages: ChatMessage[]
  isTyping: boolean
  isConnected: boolean
  token: string | null
  isOpen: boolean
}

Usage Examples

Basic Chat Implementation

vue
<script setup lang="ts">
import { computed, ref } from 'vue'
import { useChatStore } from '@sprout_lbjocson/sprout-sidekick'

const chatStore = useChatStore()
const newMessage = ref('')

// Computed properties
const messages = computed(() => chatStore.messages)
const isTyping = computed(() => chatStore.isTyping)
const isAuthenticated = computed(() => chatStore.isAuthenticated)

// Methods
async function sendMessage() {
  if (!newMessage.value.trim()) return

  try {
    await chatStore.sendMessage(newMessage.value)
    newMessage.value = ''
  } catch (error) {
    console.error('Send error:', error)
  }
}

function authenticate() {
  const token = 'mock-token-' + Date.now()
  chatStore.setToken(token)
}
</script>

Watching State Changes

typescript
import { watch } from 'vue'
import { useChatStore } from '@sprout_lbjocson/sprout-sidekick'

const chatStore = useChatStore()

// Watch for new messages
watch(
  () => chatStore.messages,
  (newMessages, oldMessages) => {
    if (newMessages.length > oldMessages.length) {
      console.log('New message received')
    }
  },
  { deep: true },
)

// Watch authentication state
watch(
  () => chatStore.isAuthenticated,
  (isAuth) => {
    if (isAuth) {
      console.log('User authenticated')
    } else {
      console.log('User logged out')
    }
  },
)

Error Handling

typescript
async function handleSendMessage(text: string) {
  try {
    await chatStore.sendMessage(text)
  } catch (error) {
    if (error.message === 'Not authenticated') {
      // Redirect to authentication
      showAuthModal()
    } else {
      // Handle other errors
      showErrorMessage('Failed to send message')
    }
  }
}