* add platform guards * add service management * fix types * move to zustand for servicehub * update App Updater * update tauri missing move * update app updater * refactor: move PlatformFeatures to separate const file 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * change tauri fetch name * update implementation * update extension fetch * make web version run properly * disabled unused web settings * fix all tests * fix lint * fix tests * add mock for extension * fix build * update make and mise * fix tsconfig for web-extensions * fix loader type * cleanup * fix test * update error handling + mcp should be working * Update mcp init * use separate is_web_app build property * Remove fixed model catalog url * fix additional tests * fix download issue (event emitter not implemented correctly) * Update Title html * fix app logs * update root tsx render timing --------- Co-authored-by: Claude <noreply@anthropic.com>
105 lines
2.5 KiB
TypeScript
105 lines
2.5 KiB
TypeScript
/**
|
|
* Shared IndexedDB utilities for web extensions
|
|
*/
|
|
|
|
import type { IndexedDBConfig } from '../types'
|
|
|
|
/**
|
|
* Default database configuration for Jan web extensions
|
|
*/
|
|
const DEFAULT_DB_CONFIG: IndexedDBConfig = {
|
|
dbName: 'jan-web-db',
|
|
version: 1,
|
|
stores: [
|
|
{
|
|
name: 'assistants',
|
|
keyPath: 'id',
|
|
indexes: [
|
|
{ name: 'name', keyPath: 'name' },
|
|
{ name: 'created_at', keyPath: 'created_at' }
|
|
]
|
|
},
|
|
{
|
|
name: 'threads',
|
|
keyPath: 'id',
|
|
indexes: [
|
|
{ name: 'title', keyPath: 'title' },
|
|
{ name: 'created_at', keyPath: 'created_at' },
|
|
{ name: 'updated_at', keyPath: 'updated_at' }
|
|
]
|
|
},
|
|
{
|
|
name: 'messages',
|
|
keyPath: 'id',
|
|
indexes: [
|
|
{ name: 'thread_id', keyPath: 'thread_id' },
|
|
{ name: 'created_at', keyPath: 'created_at' }
|
|
]
|
|
}
|
|
]
|
|
}
|
|
|
|
/**
|
|
* Shared IndexedDB instance
|
|
*/
|
|
let sharedDB: IDBDatabase | null = null
|
|
|
|
/**
|
|
* Get or create the shared IndexedDB instance
|
|
*/
|
|
export const getSharedDB = async (config: IndexedDBConfig = DEFAULT_DB_CONFIG): Promise<IDBDatabase> => {
|
|
if (sharedDB && sharedDB.name === config.dbName) {
|
|
return sharedDB
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const request = indexedDB.open(config.dbName, config.version)
|
|
|
|
request.onerror = () => {
|
|
reject(new Error(`Failed to open database: ${request.error?.message}`))
|
|
}
|
|
|
|
request.onsuccess = () => {
|
|
sharedDB = request.result
|
|
resolve(sharedDB)
|
|
}
|
|
|
|
request.onupgradeneeded = (event) => {
|
|
const db = (event.target as IDBOpenDBRequest).result
|
|
|
|
// Create object stores
|
|
for (const store of config.stores) {
|
|
let objectStore: IDBObjectStore
|
|
|
|
if (db.objectStoreNames.contains(store.name)) {
|
|
// Store exists, might need to update indexes
|
|
continue
|
|
} else {
|
|
// Create new store
|
|
objectStore = db.createObjectStore(store.name, { keyPath: store.keyPath })
|
|
}
|
|
|
|
// Create indexes
|
|
if (store.indexes) {
|
|
for (const index of store.indexes) {
|
|
try {
|
|
objectStore.createIndex(index.name, index.keyPath, { unique: index.unique || false })
|
|
} catch (error) {
|
|
// Index might already exist, ignore
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Close the shared database connection
|
|
*/
|
|
export const closeSharedDB = () => {
|
|
if (sharedDB) {
|
|
sharedDB.close()
|
|
sharedDB = null
|
|
}
|
|
} |