Skip to main content

Overview

The @proj-airi/stage-ui package provides the core business components, state management stores, and composables shared across AIRI stage applications (stage-web, stage-tamagotchi, stage-pocket).

Installation

npm install @proj-airi/stage-ui
This package is marked as private and is intended for use within the AIRI monorepo.

Package Structure

The package is organized into several key areas:
  • Components: Business-specific Vue components
  • Composables: Reusable Vue composition functions
  • Stores: Pinia state management stores
  • Types: TypeScript type definitions
  • Utils: Utility functions
  • Workers: Web Workers for background tasks
  • Tools: Tool integrations

Exports

The package provides multiple export paths for different use cases:
import { /* components */ } from '@proj-airi/stage-ui'
import { /* composables */ } from '@proj-airi/stage-ui/composables'
import { /* stores */ } from '@proj-airi/stage-ui/stores'
import { /* types */ } from '@proj-airi/stage-ui/types'
import { /* utils */ } from '@proj-airi/stage-ui/utils'
import { /* workers */ } from '@proj-airi/stage-ui/workers'

Components

Stage UI includes a comprehensive set of business components:

Component Categories

  • Auth: Authentication and user management
  • Data Pane: Data visualization and management
  • Gadgets: Interactive widgets and tools
  • Graphics: Visual rendering components
  • Layouts: Page and section layouts
  • Markdown: Markdown rendering and editing
  • Menu: Navigation and menu systems
  • Misc: Utility components
  • Modules: Module-specific components
  • Physics: Physics simulation components
  • Scenarios: Use-case-specific components
  • Widgets: Reusable widget components

Usage Example

<script setup lang="ts">
import { SomeComponent } from '@proj-airi/stage-ui'
</script>

<template>
  <SomeComponent />
</template>

Composables

Vue composables for common functionality:

Audio Composables

import { useAudioRecorder } from '@proj-airi/stage-ui/composables/audio'

const { startRecording, stopRecording, audioData } = useAudioRecorder({
  sampleRate: 16000
})

Canvas Utilities

import { useCanvasAlpha } from '@proj-airi/stage-ui/composables'

const { getAlphaAt, isTransparent } = useCanvasAlpha(canvasRef)

Chat Session

import { useChatSessionSummary } from '@proj-airi/stage-ui/composables'

const { summary, generateSummary } = useChatSessionSummary()

Analytics

import { useAnalytics } from '@proj-airi/stage-ui/composables'

const analytics = useAnalytics()
analytics.track('event_name', { property: 'value' })

Optimistic Updates

import { useOptimistic } from '@proj-airi/stage-ui/composables'

const { data, mutate } = useOptimistic(initialData, {
  onMutate: async (newData) => {
    // Optimistic update
    return newData
  },
  onError: (error, rollback) => {
    // Handle error and rollback
    rollback()
  }
})

Markdown Processing

import { useMarkdownProcessor } from '@proj-airi/stage-ui/composables'

const { process, render } = useMarkdownProcessor()
const html = await process('# Hello World')

LLM Marker Parser

import { useLLMMarkerParser } from '@proj-airi/stage-ui/composables'

const parser = useLLMMarkerParser()
const parsed = parser.parse('<thinking>Some thought</thinking>Output')

Stores

Pinia stores for state management:

AI Store

import { useAIStore } from '@proj-airi/stage-ui/stores/ai'

const aiStore = useAIStore()
const response = await aiStore.generate({
  model: 'gpt-4',
  prompt: 'Hello'
})

Audio Store

import { useAudioStore } from '@proj-airi/stage-ui/stores/audio'

const audioStore = useAudioStore()
audioStore.setVolume(0.8)
audioStore.playSound('notification')

Character Store

import { useCharacterStore } from '@proj-airi/stage-ui/stores/character'

const characterStore = useCharacterStore()
const character = await characterStore.loadCharacter('character-id')

Characters Store

import { useCharactersStore } from '@proj-airi/stage-ui/stores/characters'

const charactersStore = useCharactersStore()
const list = await charactersStore.fetchCharacters()

Chat Store

import { useChatStore } from '@proj-airi/stage-ui/stores/chat'

const chatStore = useChatStore()
await chatStore.sendMessage({
  content: 'Hello',
  role: 'user'
})

Providers Store

import { useProvidersStore } from '@proj-airi/stage-ui/stores/providers'

const providersStore = useProvidersStore()
const providers = providersStore.getAvailableProviders()

Settings Store

import { useSettingsStore } from '@proj-airi/stage-ui/stores/settings'

const settingsStore = useSettingsStore()
settingsStore.updateSetting('theme', 'dark')

Display Models Store

import { useDisplayModelsStore } from '@proj-airi/stage-ui/stores/display-models'

const displayModelsStore = useDisplayModelsStore()
const model = displayModelsStore.getCurrentModel()

Types

TypeScript type definitions:
import type {
  Character,
  ChatMessage,
  Provider,
  Settings,
  AIModel
} from '@proj-airi/stage-ui/types'

Utils

Utility functions:
import { formatDate, parseMarkdown, sanitizeHtml } from '@proj-airi/stage-ui/utils'

const formatted = formatDate(new Date())
const html = parseMarkdown('# Title')
const clean = sanitizeHtml(userInput)

TTS Utilities

import { generateSpeech, voices } from '@proj-airi/stage-ui/utils/tts'

const audio = await generateSpeech({
  text: 'Hello world',
  voice: voices[0],
  speed: 1.0
})

Workers

Web Workers for background processing:

VAD Worker

import VADWorker from '@proj-airi/stage-ui/workers/vad'

const worker = new VADWorker()
worker.postMessage({
  type: 'init',
  config: { sampleRate: 16000 }
})

Kokoro Worker

import KokoroWorker from '@proj-airi/stage-ui/workers/kokoro'

const worker = new KokoroWorker()
worker.postMessage({
  type: 'process',
  audio: audioData
})

Integration with Stage Applications

Stage Web

// In stage-web app
import { useChatStore } from '@proj-airi/stage-ui/stores/chat'
import { ChatPanel } from '@proj-airi/stage-ui/components'

const chatStore = useChatStore()

Stage Tamagotchi

// In stage-tamagotchi app
import { useCharacterStore } from '@proj-airi/stage-ui/stores/character'
import { CharacterView } from '@proj-airi/stage-ui/components'

const characterStore = useCharacterStore()
Stage UI integrates with other stage packages:
  • @proj-airi/stage-ui-three: Three.js rendering components
  • @proj-airi/stage-ui-live2d: Live2D character rendering
  • @proj-airi/stage-shared: Shared logic and utilities
  • @proj-airi/ui: Base UI component primitives
  • @proj-airi/audio: Audio processing utilities

Dependencies

Key dependencies include:
  • Vue 3 and Vue Router
  • Pinia for state management
  • VueUse for composition utilities
  • XSAI packages for AI operations
  • transformers.js for ML models
  • DOMPurify for HTML sanitization
  • date-fns for date handling

Best Practices

Prefer composables over options API for better reusability and type safety.
Import stores only when needed to reduce initial bundle size.
Always use TypeScript imports for better IDE support and type checking.
Use Pinia stores for cross-component state rather than prop drilling.
Use Web Workers for CPU-intensive tasks like audio processing and ML inference.

Next Steps

Audio Package

Learn about audio processing utilities

Server SDK

Connect to AIRI server runtime

Build docs developers (and LLMs) love