e5cf25a267
Major architectural improvements: - Renamed AgentSession → Agent (state/ → agent/) - Removed id field from AgentState - Fixed transport abstraction to pass messages directly instead of using callbacks - Eliminated circular dependencies in transport creation Transport changes: - Changed signature: run(messages, userMessage, config, signal) - Removed getMessages callback from ProviderTransport and AppTransport - Transports now filter attachments internally Session storage: - Added SessionRepository with IndexedDB backend - Auto-save sessions after first exchange - Auto-generate titles from first user message - Session list dialog with search and delete - Persistent storage permission dialog - Browser extension now auto-loads last session UI improvements: - ChatPanel creates single AgentInterface instance in setAgent() - Added drag & drop file upload to MessageEditor - Fixed artifacts panel auto-opening on session load - Added "Drop files here" i18n strings - Changed "Continue Without Saving" → "Continue Anyway" Web example: - Complete rewrite of main.ts with clean architecture - Added check script to package.json - Session management with URL state - Editable session titles Browser extension: - Added full session storage support - History and new session buttons - Auto-load most recent session on open - Session titles in header
61 lines
1.9 KiB
TypeScript
61 lines
1.9 KiB
TypeScript
import { LocalStorageBackend } from "./backends/local-storage-backend.js";
|
|
import { ProviderKeysRepository } from "./repositories/provider-keys-repository.js";
|
|
import { SessionRepository } from "./repositories/session-repository.js";
|
|
import { SettingsRepository } from "./repositories/settings-repository.js";
|
|
import type { AppStorageConfig } from "./types.js";
|
|
|
|
/**
|
|
* High-level storage API aggregating all repositories.
|
|
* Apps configure backends and use repositories through this interface.
|
|
*/
|
|
export class AppStorage {
|
|
readonly settings: SettingsRepository;
|
|
readonly providerKeys: ProviderKeysRepository;
|
|
readonly sessions?: SessionRepository;
|
|
|
|
constructor(config: AppStorageConfig = {}) {
|
|
// Use LocalStorage with prefixes as defaults
|
|
const settingsBackend = config.settings ?? new LocalStorageBackend("settings");
|
|
const providerKeysBackend = config.providerKeys ?? new LocalStorageBackend("providerKeys");
|
|
|
|
this.settings = new SettingsRepository(settingsBackend);
|
|
this.providerKeys = new ProviderKeysRepository(providerKeysBackend);
|
|
|
|
// Session storage is optional
|
|
if (config.sessions) {
|
|
this.sessions = new SessionRepository(config.sessions);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Global instance management
|
|
let globalAppStorage: AppStorage | null = null;
|
|
|
|
/**
|
|
* Get the global AppStorage instance.
|
|
* Throws if not initialized.
|
|
*/
|
|
export function getAppStorage(): AppStorage {
|
|
if (!globalAppStorage) {
|
|
throw new Error("AppStorage not initialized. Call setAppStorage() first.");
|
|
}
|
|
return globalAppStorage;
|
|
}
|
|
|
|
/**
|
|
* Set the global AppStorage instance.
|
|
*/
|
|
export function setAppStorage(storage: AppStorage): void {
|
|
globalAppStorage = storage;
|
|
}
|
|
|
|
/**
|
|
* Initialize AppStorage with default configuration if not already set.
|
|
*/
|
|
export function initAppStorage(config: AppStorageConfig = {}): AppStorage {
|
|
if (!globalAppStorage) {
|
|
globalAppStorage = new AppStorage(config);
|
|
}
|
|
return globalAppStorage;
|
|
}
|