feat: initial implementation of Light Chat app with React, Capacitor, and comprehensive tests
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* Session Management Service
|
||||
* Handles creation, storage, and retrieval of chat sessions
|
||||
*/
|
||||
|
||||
const STORAGE_KEY = 'light-chat-sessions'
|
||||
const CONFIG_KEY = 'light-chat-config'
|
||||
|
||||
/**
|
||||
* Generate unique session ID
|
||||
* @returns {string}
|
||||
*/
|
||||
function generateId() {
|
||||
return Date.now().toString(36) + Math.random().toString(36).substr(2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Default session structure
|
||||
*/
|
||||
function createSession(endpoint = '', systemPrompt = '') {
|
||||
return {
|
||||
id: generateId(),
|
||||
name: `Session ${new Date().toLocaleTimeString()}`,
|
||||
endpoint,
|
||||
systemPrompt,
|
||||
messages: [],
|
||||
createdAt: Date.now(),
|
||||
updatedAt: Date.now()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all sessions from storage
|
||||
* @returns {Array}
|
||||
*/
|
||||
export function loadSessions() {
|
||||
try {
|
||||
const data = localStorage.getItem(STORAGE_KEY)
|
||||
return data ? JSON.parse(data) : []
|
||||
} catch (error) {
|
||||
console.error('Failed to load sessions:', error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save sessions to storage
|
||||
* @param {Array} sessions
|
||||
*/
|
||||
export function saveSessions(sessions) {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(sessions))
|
||||
} catch (error) {
|
||||
console.error('Failed to save sessions:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load API configuration
|
||||
* @returns {Object} { endpoint, systemPrompt }
|
||||
*/
|
||||
export function loadConfig() {
|
||||
try {
|
||||
const data = localStorage.getItem(CONFIG_KEY)
|
||||
return data ? JSON.parse(data) : { endpoint: '', systemPrompt: '' }
|
||||
} catch (error) {
|
||||
console.error('Failed to load config:', error)
|
||||
return { endpoint: '', systemPrompt: '' }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save API configuration
|
||||
* @param {Object} config
|
||||
*/
|
||||
export function saveConfig(config) {
|
||||
try {
|
||||
localStorage.setItem(CONFIG_KEY, JSON.stringify(config))
|
||||
} catch (error) {
|
||||
console.error('Failed to save config:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new session
|
||||
* @param {Object} options
|
||||
* @returns {Object} new session
|
||||
*/
|
||||
export function addSession(options = {}) {
|
||||
const sessions = loadSessions()
|
||||
const newSession = createSession(
|
||||
options.endpoint,
|
||||
options.systemPrompt
|
||||
)
|
||||
sessions.push(newSession)
|
||||
saveSessions(sessions)
|
||||
return newSession
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a session
|
||||
* @param {string} sessionId
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function deleteSession(sessionId) {
|
||||
const sessions = loadSessions()
|
||||
const filtered = sessions.filter(s => s.id !== sessionId)
|
||||
if (filtered.length === sessions.length) {
|
||||
return false
|
||||
}
|
||||
saveSessions(filtered)
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a session
|
||||
* @param {string} sessionId
|
||||
* @param {Object} updates
|
||||
* @returns {Object|null} updated session or null
|
||||
*/
|
||||
export function updateSession(sessionId, updates) {
|
||||
const sessions = loadSessions()
|
||||
const index = sessions.findIndex(s => s.id === sessionId)
|
||||
|
||||
if (index === -1) {
|
||||
return null
|
||||
}
|
||||
|
||||
sessions[index] = {
|
||||
...sessions[index],
|
||||
...updates,
|
||||
updatedAt: Date.now()
|
||||
}
|
||||
|
||||
// Update name if messages exist and name is default
|
||||
if (sessions[index].messages.length > 0 && sessions[index].name.startsWith('Session')) {
|
||||
sessions[index].name = `Chat ${new Date(sessions[index].createdAt).toLocaleDateString()}`
|
||||
}
|
||||
|
||||
saveSessions(sessions)
|
||||
return sessions[index]
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific session
|
||||
* @param {string} sessionId
|
||||
* @returns {Object|null}
|
||||
*/
|
||||
export function getSession(sessionId) {
|
||||
const sessions = loadSessions()
|
||||
return sessions.find(s => s.id === sessionId) || null
|
||||
}
|
||||
|
||||
/**
|
||||
* Add message to a session
|
||||
* @param {string} sessionId
|
||||
* @param {Object} message - { role: 'user'|'assistant', content: string }
|
||||
* @returns {Object|null} updated session
|
||||
*/
|
||||
export function addMessage(sessionId, message) {
|
||||
const session = getSession(sessionId)
|
||||
|
||||
if (!session) {
|
||||
return null
|
||||
}
|
||||
|
||||
session.messages.push(message)
|
||||
return updateSession(sessionId, { messages: session.messages })
|
||||
}
|
||||
Reference in New Issue
Block a user