/** * LocalStorage Storage Adapter * * Browser-compatible storage using the Web Storage API (localStorage). * Persistent across page reloads but limited to ~5MB per origin. * * Supports optional AES-256-GCM at-rest encryption when an encryption key * is provided, preventing clear-text storage of sensitive values. */ import { BaseStorageAdapter } from './base'; import type { SetOptions, MessageHandler, Unsubscribe } from '../types'; /** * Options for the LocalStorage adapter. */ export interface LocalStorageAdapterOptions { /** * Key prefix for namespacing. * @default 'frontmcp:' */ prefix?: string; /** * Optional 32-byte AES-256-GCM encryption key. * When provided, all values are encrypted at rest in localStorage. */ encryptionKey?: Uint8Array; /** * Whether to allow plaintext storage when no encryption key is provided. * @default true */ allowPlaintext?: boolean; } /** * Browser localStorage-based storage adapter. * * Features: * - Persistent across page reloads * - Synchronous underlying API (async interface for consistency) * - TTL support via stored expiration timestamps * - Size-limited (~5MB per origin) * * Limitations: * - No pub/sub support * - incr/decr/incrBy are non-atomic (read-then-write); do not assume atomicity under concurrent access * - String-only values (matches StorageAdapter contract) * - Pattern matching uses simple iteration */ export declare class LocalStorageAdapter extends BaseStorageAdapter { protected readonly backendName = "localstorage"; private readonly prefix; private readonly encryptionKey; private readonly allowPlaintext; private readonly encoder; private readonly decoder; constructor(options?: LocalStorageAdapterOptions); private assertAvailable; private key; private stripPrefix; connect(): Promise; disconnect(): Promise; ping(): Promise; get(key: string): Promise; set(key: string, value: string, options?: SetOptions): Promise; protected doSet(key: string, value: string, options?: SetOptions): Promise; delete(key: string): Promise; exists(key: string): Promise; mget(keys: string[]): Promise<(string | null)[]>; mset(entries: { key: string; value: string; options?: SetOptions; }[]): Promise; mdelete(keys: string[]): Promise; expire(key: string, ttlSeconds: number): Promise; ttl(key: string): Promise; keys(pattern?: string): Promise; count(pattern?: string): Promise; incr(key: string): Promise; decr(key: string): Promise; incrBy(key: string, amount: number): Promise; publish(): Promise; subscribe(_channel: string, _handler: MessageHandler): Promise; supportsPubSub(): boolean; private matchPattern; }