{"version":3,"sources":["../../src/session/types.ts","../../src/utils/id.ts","../../src/session/InMemorySessionStore.ts","../../src/session/RedisSessionStore.ts","../../src/session/ZeroDBSessionStore.ts","../../src/session/SessionManager.ts"],"names":["ExpirationStrategy","StorageBackend","SessionEvent"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Type definitions for session management\n */\n\n/**\n * Session data stored for each session\n */\nexport interface SessionData {\n  /** User ID associated with the session */\n  userId: string\n  /** Custom session data */\n  data: Record<string, any>\n  /** Timestamp when session was created (milliseconds) */\n  createdAt: number\n  /** Timestamp when session was last accessed (milliseconds) */\n  lastAccessedAt: number\n  /** Timestamp when session expires (milliseconds) */\n  expiresAt: number\n  /** IP address of the session (optional) */\n  ipAddress?: string\n  /** User agent string (optional) */\n  userAgent?: string\n  /** Session metadata */\n  metadata?: Record<string, any>\n}\n\n/**\n * Session object returned to consumers\n */\nexport interface Session {\n  /** Unique session identifier */\n  sessionId: string\n  /** User ID associated with the session */\n  userId: string\n  /** Custom session data */\n  data: Record<string, any>\n  /** Timestamp when session was created (milliseconds) */\n  createdAt: number\n  /** Timestamp when session was last accessed (milliseconds) */\n  lastAccessedAt: number\n  /** Timestamp when session expires (milliseconds) */\n  expiresAt: number\n  /** Whether the session is expired */\n  isExpired: boolean\n  /** IP address of the session (optional) */\n  ipAddress?: string\n  /** User agent string (optional) */\n  userAgent?: string\n  /** Session metadata */\n  metadata?: Record<string, any>\n}\n\n/**\n * Expiration strategy for sessions\n */\nexport enum ExpirationStrategy {\n  /** Session expires after a fixed time from creation */\n  FIXED = 'fixed',\n  /** Session expiration extends on each access (sliding window) */\n  SLIDING = 'sliding',\n  /** Session uses both fixed and sliding expiration */\n  HYBRID = 'hybrid'\n}\n\n/**\n * Storage backend type for sessions\n */\nexport enum StorageBackend {\n  /** In-memory storage (not persistent) */\n  MEMORY = 'memory',\n  /** Redis storage (persistent, distributed) */\n  REDIS = 'redis',\n  /** ZeroDB storage (persistent, encrypted) */\n  ZERODB = 'zerodb'\n}\n\n/**\n * Base configuration for session manager\n */\nexport interface BaseSessionConfig {\n  /** Default TTL in seconds (default: 3600 = 1 hour) */\n  ttl?: number\n  /** Expiration strategy (default: sliding) */\n  expirationStrategy?: ExpirationStrategy\n  /** Namespace/prefix for session keys */\n  namespace?: string\n  /** Enable session data encryption */\n  encryptData?: boolean\n  /** Encryption key (required if encryptData is true) */\n  encryptionKey?: string\n  /** Maximum concurrent sessions per user (0 = unlimited) */\n  maxSessionsPerUser?: number\n  /** Enable session locking for concurrent access */\n  enableLocking?: boolean\n  /** Lock timeout in milliseconds (default: 5000) */\n  lockTimeout?: number\n  /** Cleanup interval in milliseconds (default: 300000 = 5 minutes) */\n  cleanupInterval?: number\n  /** Enable automatic cleanup of expired sessions */\n  autoCleanup?: boolean\n}\n\n/**\n * Configuration for in-memory session store\n */\nexport interface InMemorySessionConfig extends BaseSessionConfig {\n  type: 'memory'\n  /** Maximum number of sessions to store (LRU eviction) */\n  maxSessions?: number\n}\n\n/**\n * Configuration for Redis session store\n */\nexport interface RedisSessionConfig extends BaseSessionConfig {\n  type: 'redis'\n  /** Redis connection URL */\n  url?: string\n  /** Redis host */\n  host?: string\n  /** Redis port */\n  port?: number\n  /** Redis password */\n  password?: string\n  /** Redis database number */\n  db?: number\n  /** Key prefix for Redis keys */\n  keyPrefix?: string\n}\n\n/**\n * Configuration for ZeroDB session store\n */\nexport interface ZeroDBSessionConfig extends BaseSessionConfig {\n  type: 'zerodb'\n  /** ZeroDB project ID */\n  projectId: string\n  /** ZeroDB API key */\n  apiKey: string\n  /** Table name for sessions */\n  tableName?: string\n}\n\n/**\n * Union type for all session configurations\n */\nexport type SessionConfig = InMemorySessionConfig | RedisSessionConfig | ZeroDBSessionConfig\n\n/**\n * Options for creating a new session\n */\nexport interface CreateSessionOptions {\n  /** Custom TTL in seconds (overrides default) */\n  ttl?: number\n  /** IP address of the client */\n  ipAddress?: string\n  /** User agent string */\n  userAgent?: string\n  /** Custom metadata */\n  metadata?: Record<string, any>\n}\n\n/**\n * Options for updating a session\n */\nexport interface UpdateSessionOptions {\n  /** Whether to update the lastAccessedAt timestamp */\n  updateLastAccessed?: boolean\n  /** Merge data instead of replacing */\n  merge?: boolean\n}\n\n/**\n * Options for refreshing a session\n */\nexport interface RefreshSessionOptions {\n  /** Custom TTL in seconds (overrides default) */\n  ttl?: number\n}\n\n/**\n * Options for listing sessions\n */\nexport interface ListSessionsOptions {\n  /** Include expired sessions */\n  includeExpired?: boolean\n  /** Limit number of results */\n  limit?: number\n  /** Offset for pagination */\n  offset?: number\n}\n\n/**\n * Session statistics\n */\nexport interface SessionStats {\n  /** Total number of sessions */\n  totalSessions: number\n  /** Number of active (non-expired) sessions */\n  activeSessions: number\n  /** Number of expired sessions */\n  expiredSessions: number\n  /** Sessions grouped by user ID */\n  sessionsByUser?: Record<string, number>\n  /** Average session duration in milliseconds */\n  averageDuration?: number\n}\n\n/**\n * Session store interface that all storage backends must implement\n */\nexport interface SessionStore {\n  /**\n   * Get a session by ID\n   */\n  get(sessionId: string): Promise<SessionData | null>\n\n  /**\n   * Set/update a session\n   */\n  set(sessionId: string, data: SessionData): Promise<void>\n\n  /**\n   * Delete a session\n   */\n  delete(sessionId: string): Promise<boolean>\n\n  /**\n   * Check if a session exists\n   */\n  exists(sessionId: string): Promise<boolean>\n\n  /**\n   * Get all sessions for a user\n   */\n  getByUserId(userId: string): Promise<Map<string, SessionData>>\n\n  /**\n   * Delete all sessions for a user\n   */\n  deleteByUserId(userId: string): Promise<number>\n\n  /**\n   * Get all session IDs\n   */\n  getAllSessionIds(): Promise<string[]>\n\n  /**\n   * Remove expired sessions\n   */\n  cleanup(): Promise<number>\n\n  /**\n   * Get session statistics\n   */\n  getStats(): Promise<SessionStats>\n\n  /**\n   * Acquire a lock for a session\n   */\n  acquireLock?(sessionId: string, timeout: number): Promise<boolean>\n\n  /**\n   * Release a lock for a session\n   */\n  releaseLock?(sessionId: string): Promise<void>\n\n  /**\n   * Close the store connection\n   */\n  close?(): Promise<void>\n}\n\n/**\n * Session event types\n */\nexport enum SessionEvent {\n  CREATED = 'session:created',\n  UPDATED = 'session:updated',\n  REFRESHED = 'session:refreshed',\n  DELETED = 'session:deleted',\n  EXPIRED = 'session:expired',\n  LOCKED = 'session:locked',\n  UNLOCKED = 'session:unlocked'\n}\n\n/**\n * Session event payload\n */\nexport interface SessionEventPayload {\n  /** Session ID */\n  sessionId: string\n  /** User ID */\n  userId: string\n  /** Event type */\n  event: SessionEvent\n  /** Timestamp */\n  timestamp: number\n  /** Additional data */\n  data?: Record<string, any>\n}\n","/**\n * ID generation utilities\n */\n\n/**\n * Generate a unique ID with optional prefix\n */\nexport function generateId(prefix?: string): string {\n  const timestamp = Date.now().toString(36);\n  const randomPart = Math.random().toString(36).substring(2, 9);\n  const id = `${timestamp}-${randomPart}`;\n  return prefix ? `${prefix}-${id}` : id;\n}\n\n/**\n * Generate a short unique ID\n */\nexport function generateShortId(): string {\n  return Math.random().toString(36).substring(2, 9);\n}\n","/**\n * In-memory session store implementation\n * Provides fast session storage using Maps with LRU eviction\n */\n\nimport {\n  SessionStore,\n  SessionData,\n  SessionStats\n} from './types'\n\n/**\n * LRU (Least Recently Used) entry for tracking access order\n */\ninterface LRUEntry {\n  sessionId: string\n  accessTime: number\n}\n\n/**\n * In-memory session store with LRU eviction\n */\nexport class InMemorySessionStore implements SessionStore {\n  private sessions: Map<string, SessionData>\n  private userSessions: Map<string, Set<string>>\n  private locks: Map<string, number>\n  private accessOrder: LRUEntry[]\n  private maxSessions: number\n\n  constructor(maxSessions: number = 10000) {\n    this.sessions = new Map()\n    this.userSessions = new Map()\n    this.locks = new Map()\n    this.accessOrder = []\n    this.maxSessions = maxSessions\n  }\n\n  /**\n   * Get a session by ID\n   */\n  async get(sessionId: string): Promise<SessionData | null> {\n    const session = this.sessions.get(sessionId)\n    if (!session) {\n      return null\n    }\n\n    // Update access order for LRU\n    this.updateAccessOrder(sessionId)\n\n    return { ...session }\n  }\n\n  /**\n   * Set/update a session\n   */\n  async set(sessionId: string, data: SessionData): Promise<void> {\n    // Check if we need to evict old sessions\n    if (!this.sessions.has(sessionId) && this.sessions.size >= this.maxSessions) {\n      this.evictOldest()\n    }\n\n    // Store session\n    this.sessions.set(sessionId, { ...data })\n\n    // Update user sessions index\n    const userSessionSet = this.userSessions.get(data.userId) || new Set()\n    userSessionSet.add(sessionId)\n    this.userSessions.set(data.userId, userSessionSet)\n\n    // Update access order\n    this.updateAccessOrder(sessionId)\n  }\n\n  /**\n   * Delete a session\n   */\n  async delete(sessionId: string): Promise<boolean> {\n    const session = this.sessions.get(sessionId)\n    if (!session) {\n      return false\n    }\n\n    // Remove from sessions map\n    this.sessions.delete(sessionId)\n\n    // Remove from user sessions index\n    const userSessionSet = this.userSessions.get(session.userId)\n    if (userSessionSet) {\n      userSessionSet.delete(sessionId)\n      if (userSessionSet.size === 0) {\n        this.userSessions.delete(session.userId)\n      }\n    }\n\n    // Remove from access order\n    this.accessOrder = this.accessOrder.filter(entry => entry.sessionId !== sessionId)\n\n    // Remove lock if exists\n    this.locks.delete(sessionId)\n\n    return true\n  }\n\n  /**\n   * Check if a session exists\n   */\n  async exists(sessionId: string): Promise<boolean> {\n    return this.sessions.has(sessionId)\n  }\n\n  /**\n   * Get all sessions for a user\n   */\n  async getByUserId(userId: string): Promise<Map<string, SessionData>> {\n    const result = new Map<string, SessionData>()\n    const sessionIds = this.userSessions.get(userId)\n\n    if (!sessionIds) {\n      return result\n    }\n\n    Array.from(sessionIds).forEach(sessionId => {\n      const session = this.sessions.get(sessionId)\n      if (session) {\n        result.set(sessionId, { ...session })\n      }\n    })\n\n    return result\n  }\n\n  /**\n   * Delete all sessions for a user\n   */\n  async deleteByUserId(userId: string): Promise<number> {\n    const sessionIds = this.userSessions.get(userId)\n    if (!sessionIds) {\n      return 0\n    }\n\n    let deletedCount = 0\n    const sessionIdArray = Array.from(sessionIds)\n    for (const sessionId of sessionIdArray) {\n      const deleted = await this.delete(sessionId)\n      if (deleted) {\n        deletedCount++\n      }\n    }\n\n    return deletedCount\n  }\n\n  /**\n   * Get all session IDs\n   */\n  async getAllSessionIds(): Promise<string[]> {\n    return Array.from(this.sessions.keys())\n  }\n\n  /**\n   * Remove expired sessions\n   */\n  async cleanup(): Promise<number> {\n    const now = Date.now()\n    let cleanedCount = 0\n    const expiredSessionIds: string[] = []\n\n    // Find expired sessions\n    Array.from(this.sessions.entries()).forEach(([sessionId, session]) => {\n      if (session.expiresAt <= now) {\n        expiredSessionIds.push(sessionId)\n      }\n    })\n\n    // Delete expired sessions\n    for (const sessionId of expiredSessionIds) {\n      const deleted = await this.delete(sessionId)\n      if (deleted) {\n        cleanedCount++\n      }\n    }\n\n    return cleanedCount\n  }\n\n  /**\n   * Get session statistics\n   */\n  async getStats(): Promise<SessionStats> {\n    const now = Date.now()\n    let activeSessions = 0\n    let expiredSessions = 0\n    let totalDuration = 0\n    const sessionsByUser: Record<string, number> = {}\n\n    Array.from(this.sessions.entries()).forEach(([, session]) => {\n      if (session.expiresAt > now) {\n        activeSessions++\n      } else {\n        expiredSessions++\n      }\n\n      // Track sessions by user\n      sessionsByUser[session.userId] = (sessionsByUser[session.userId] || 0) + 1\n\n      // Calculate duration\n      const duration = session.lastAccessedAt - session.createdAt\n      totalDuration += duration\n    })\n\n    const totalSessions = this.sessions.size\n    const averageDuration = totalSessions > 0 ? totalDuration / totalSessions : 0\n\n    return {\n      totalSessions,\n      activeSessions,\n      expiredSessions,\n      sessionsByUser,\n      averageDuration\n    }\n  }\n\n  /**\n   * Acquire a lock for a session\n   */\n  async acquireLock(sessionId: string, timeout: number): Promise<boolean> {\n    const now = Date.now()\n    const existingLock = this.locks.get(sessionId)\n\n    // Check if lock exists and is still valid\n    if (existingLock && existingLock > now) {\n      return false\n    }\n\n    // Acquire lock\n    this.locks.set(sessionId, now + timeout)\n    return true\n  }\n\n  /**\n   * Release a lock for a session\n   */\n  async releaseLock(sessionId: string): Promise<void> {\n    this.locks.delete(sessionId)\n  }\n\n  /**\n   * Update access order for LRU tracking\n   */\n  private updateAccessOrder(sessionId: string): void {\n    // Remove existing entry\n    this.accessOrder = this.accessOrder.filter(entry => entry.sessionId !== sessionId)\n\n    // Add to end (most recently used)\n    this.accessOrder.push({\n      sessionId,\n      accessTime: Date.now()\n    })\n  }\n\n  /**\n   * Evict the oldest (least recently used) session\n   */\n  private evictOldest(): void {\n    if (this.accessOrder.length === 0) {\n      return\n    }\n\n    // Get least recently used session\n    const oldest = this.accessOrder[0]\n    if (oldest) {\n      this.delete(oldest.sessionId)\n    }\n  }\n\n  /**\n   * Get the number of sessions in the store\n   */\n  get size(): number {\n    return this.sessions.size\n  }\n\n  /**\n   * Clear all sessions (for testing)\n   */\n  async clear(): Promise<void> {\n    this.sessions.clear()\n    this.userSessions.clear()\n    this.locks.clear()\n    this.accessOrder = []\n  }\n}\n","/**\n * Redis session store implementation\n * Provides persistent, distributed session storage using Redis\n */\n\nimport Redis, { RedisOptions } from 'ioredis'\nimport {\n  SessionStore,\n  SessionData,\n  SessionStats,\n  RedisSessionConfig\n} from './types'\n\n/**\n * Redis session store with automatic expiration\n */\nexport class RedisSessionStore implements SessionStore {\n  private redis: Redis\n  private keyPrefix: string\n  private userIndexPrefix: string\n\n  constructor(config: Omit<RedisSessionConfig, 'type'>) {\n    const redisOptions: RedisOptions = {\n      host: config.host || 'localhost',\n      port: config.port || 6379,\n      password: config.password,\n      db: config.db || 0,\n      keyPrefix: config.keyPrefix || 'session:'\n    }\n\n    if (config.url) {\n      this.redis = new Redis(config.url, redisOptions)\n    } else {\n      this.redis = new Redis(redisOptions)\n    }\n\n    this.keyPrefix = config.keyPrefix || 'session:'\n    this.userIndexPrefix = `${this.keyPrefix}user:`\n  }\n\n  /**\n   * Get the full Redis key for a session\n   */\n  private getSessionKey(sessionId: string): string {\n    return `${this.keyPrefix}${sessionId}`\n  }\n\n  /**\n   * Get the user index key\n   */\n  private getUserIndexKey(userId: string): string {\n    return `${this.userIndexPrefix}${userId}`\n  }\n\n  /**\n   * Get a session by ID\n   */\n  async get(sessionId: string): Promise<SessionData | null> {\n    const key = this.getSessionKey(sessionId)\n    const data = await this.redis.get(key)\n\n    if (!data) {\n      return null\n    }\n\n    try {\n      return JSON.parse(data) as SessionData\n    } catch (error) {\n      console.error('Failed to parse session data:', error)\n      return null\n    }\n  }\n\n  /**\n   * Set/update a session\n   */\n  async set(sessionId: string, data: SessionData): Promise<void> {\n    const key = this.getSessionKey(sessionId)\n    const userIndexKey = this.getUserIndexKey(data.userId)\n\n    // Calculate TTL in seconds\n    const ttl = Math.ceil((data.expiresAt - Date.now()) / 1000)\n\n    if (ttl <= 0) {\n      // Session already expired, don't store it\n      return\n    }\n\n    // Use pipeline for atomic operations\n    const pipeline = this.redis.pipeline()\n\n    // Store session data with expiration\n    pipeline.setex(key, ttl, JSON.stringify(data))\n\n    // Add session ID to user index\n    pipeline.sadd(userIndexKey, sessionId)\n\n    // Set expiration on user index (slightly longer than session)\n    pipeline.expire(userIndexKey, ttl + 60)\n\n    await pipeline.exec()\n  }\n\n  /**\n   * Delete a session\n   */\n  async delete(sessionId: string): Promise<boolean> {\n    const key = this.getSessionKey(sessionId)\n\n    // Get session to find user ID\n    const session = await this.get(sessionId)\n    if (!session) {\n      return false\n    }\n\n    const userIndexKey = this.getUserIndexKey(session.userId)\n\n    // Use pipeline for atomic operations\n    const pipeline = this.redis.pipeline()\n    pipeline.del(key)\n    pipeline.srem(userIndexKey, sessionId)\n\n    await pipeline.exec()\n\n    return true\n  }\n\n  /**\n   * Check if a session exists\n   */\n  async exists(sessionId: string): Promise<boolean> {\n    const key = this.getSessionKey(sessionId)\n    const result = await this.redis.exists(key)\n    return result === 1\n  }\n\n  /**\n   * Get all sessions for a user\n   */\n  async getByUserId(userId: string): Promise<Map<string, SessionData>> {\n    const userIndexKey = this.getUserIndexKey(userId)\n    const sessionIds = await this.redis.smembers(userIndexKey)\n\n    const result = new Map<string, SessionData>()\n\n    // Fetch all sessions in parallel\n    const sessions = await Promise.all(\n      sessionIds.map(sessionId => this.get(sessionId))\n    )\n\n    // Add non-null sessions to result\n    sessionIds.forEach((sessionId, index) => {\n      const session = sessions[index]\n      if (session) {\n        result.set(sessionId, session)\n      }\n    })\n\n    return result\n  }\n\n  /**\n   * Delete all sessions for a user\n   */\n  async deleteByUserId(userId: string): Promise<number> {\n    const userIndexKey = this.getUserIndexKey(userId)\n    const sessionIds = await this.redis.smembers(userIndexKey)\n\n    if (sessionIds.length === 0) {\n      return 0\n    }\n\n    // Delete all sessions\n    const pipeline = this.redis.pipeline()\n\n    for (const sessionId of sessionIds) {\n      const key = this.getSessionKey(sessionId)\n      pipeline.del(key)\n    }\n\n    // Delete user index\n    pipeline.del(userIndexKey)\n\n    await pipeline.exec()\n\n    return sessionIds.length\n  }\n\n  /**\n   * Get all session IDs\n   */\n  async getAllSessionIds(): Promise<string[]> {\n    const pattern = `${this.keyPrefix}*`\n    const keys = await this.redis.keys(pattern)\n\n    return keys\n      .map(key => key.replace(this.keyPrefix, ''))\n      .filter(sessionId => !sessionId.startsWith('user:'))\n  }\n\n  /**\n   * Remove expired sessions\n   * Note: Redis handles expiration automatically, so this is a no-op\n   */\n  async cleanup(): Promise<number> {\n    // Redis automatically removes expired keys\n    // We can clean up orphaned user index entries\n    const userIndexPattern = `${this.userIndexPrefix}*`\n    const userIndexKeys = await this.redis.keys(userIndexPattern)\n\n    let cleanedCount = 0\n\n    for (const userIndexKey of userIndexKeys) {\n      const sessionIds = await this.redis.smembers(userIndexKey)\n      const orphanedIds: string[] = []\n\n      // Check which sessions no longer exist\n      for (const sessionId of sessionIds) {\n        const exists = await this.exists(sessionId)\n        if (!exists) {\n          orphanedIds.push(sessionId)\n        }\n      }\n\n      // Remove orphaned session IDs from user index\n      if (orphanedIds.length > 0) {\n        await this.redis.srem(userIndexKey, ...orphanedIds)\n        cleanedCount += orphanedIds.length\n      }\n\n      // Remove user index if empty\n      const remainingCount = await this.redis.scard(userIndexKey)\n      if (remainingCount === 0) {\n        await this.redis.del(userIndexKey)\n      }\n    }\n\n    return cleanedCount\n  }\n\n  /**\n   * Get session statistics\n   */\n  async getStats(): Promise<SessionStats> {\n    const sessionIds = await this.getAllSessionIds()\n    const now = Date.now()\n\n    let activeSessions = 0\n    let expiredSessions = 0\n    let totalDuration = 0\n    const sessionsByUser: Record<string, number> = {}\n\n    // Fetch all sessions in parallel\n    const sessions = await Promise.all(\n      sessionIds.map(sessionId => this.get(sessionId))\n    )\n\n    for (const session of sessions) {\n      if (!session) {\n        continue\n      }\n\n      if (session.expiresAt > now) {\n        activeSessions++\n      } else {\n        expiredSessions++\n      }\n\n      // Track sessions by user\n      sessionsByUser[session.userId] = (sessionsByUser[session.userId] || 0) + 1\n\n      // Calculate duration\n      const duration = session.lastAccessedAt - session.createdAt\n      totalDuration += duration\n    }\n\n    const totalSessions = sessions.filter(s => s !== null).length\n    const averageDuration = totalSessions > 0 ? totalDuration / totalSessions : 0\n\n    return {\n      totalSessions,\n      activeSessions,\n      expiredSessions,\n      sessionsByUser,\n      averageDuration\n    }\n  }\n\n  /**\n   * Acquire a lock for a session using Redis SET NX\n   */\n  async acquireLock(sessionId: string, timeout: number): Promise<boolean> {\n    const lockKey = `${this.keyPrefix}lock:${sessionId}`\n    const ttl = Math.ceil(timeout / 1000)\n\n    // Try to set lock with NX (only if not exists) and EX (expiration)\n    const result = await this.redis.set(lockKey, '1', 'EX', ttl, 'NX')\n\n    return result === 'OK'\n  }\n\n  /**\n   * Release a lock for a session\n   */\n  async releaseLock(sessionId: string): Promise<void> {\n    const lockKey = `${this.keyPrefix}lock:${sessionId}`\n    await this.redis.del(lockKey)\n  }\n\n  /**\n   * Close the Redis connection\n   */\n  async close(): Promise<void> {\n    await this.redis.quit()\n  }\n}\n","/**\n * ZeroDB session store implementation\n * Provides persistent, encrypted session storage using ZeroDB\n */\n\nimport {\n  SessionStore,\n  SessionData,\n  SessionStats,\n  ZeroDBSessionConfig\n} from './types'\n\n/**\n * ZeroDB session store with encryption support\n */\nexport class ZeroDBSessionStore implements SessionStore {\n  private projectId: string\n  private apiKey: string\n  private tableName: string\n  private baseUrl: string\n\n  constructor(config: Omit<ZeroDBSessionConfig, 'type'>) {\n    this.projectId = config.projectId\n    this.apiKey = config.apiKey\n    this.tableName = config.tableName || 'sessions'\n    this.baseUrl = 'https://api.zerodb.io/v1'\n  }\n\n  /**\n   * Make an authenticated request to ZeroDB\n   */\n  private async request(\n    method: string,\n    endpoint: string,\n    body?: any\n  ): Promise<any> {\n    const url = `${this.baseUrl}${endpoint}`\n\n    const response = await fetch(url, {\n      method,\n      headers: {\n        'Content-Type': 'application/json',\n        'Authorization': `Bearer ${this.apiKey}`,\n        'X-Project-ID': this.projectId\n      },\n      body: body ? JSON.stringify(body) : undefined\n    })\n\n    if (!response.ok) {\n      const error = await response.text()\n      throw new Error(`ZeroDB request failed: ${response.status} ${error}`)\n    }\n\n    return response.json()\n  }\n\n  /**\n   * Initialize the sessions table if it doesn't exist\n   */\n  async initialize(): Promise<void> {\n    try {\n      await this.request('POST', '/tables', {\n        name: this.tableName,\n        schema: {\n          sessionId: { type: 'string', primary: true },\n          userId: { type: 'string', indexed: true },\n          data: { type: 'json' },\n          createdAt: { type: 'number' },\n          lastAccessedAt: { type: 'number' },\n          expiresAt: { type: 'number', indexed: true },\n          ipAddress: { type: 'string', optional: true },\n          userAgent: { type: 'string', optional: true },\n          metadata: { type: 'json', optional: true }\n        }\n      })\n    } catch (error) {\n      // Table might already exist, ignore error\n      if (!(error instanceof Error) || !error.message.includes('already exists')) {\n        console.warn('Failed to initialize sessions table:', error)\n      }\n    }\n  }\n\n  /**\n   * Get a session by ID\n   */\n  async get(sessionId: string): Promise<SessionData | null> {\n    try {\n      const response = await this.request(\n        'POST',\n        `/tables/${this.tableName}/query`,\n        {\n          filter: { sessionId },\n          limit: 1\n        }\n      )\n\n      if (!response.rows || response.rows.length === 0) {\n        return null\n      }\n\n      const row = response.rows[0]\n      return {\n        userId: row.userId,\n        data: row.data,\n        createdAt: row.createdAt,\n        lastAccessedAt: row.lastAccessedAt,\n        expiresAt: row.expiresAt,\n        ipAddress: row.ipAddress,\n        userAgent: row.userAgent,\n        metadata: row.metadata\n      }\n    } catch (error) {\n      console.error('Failed to get session:', error)\n      return null\n    }\n  }\n\n  /**\n   * Set/update a session\n   */\n  async set(sessionId: string, data: SessionData): Promise<void> {\n    try {\n      await this.request('POST', `/tables/${this.tableName}/upsert`, {\n        rows: [\n          {\n            sessionId,\n            userId: data.userId,\n            data: data.data,\n            createdAt: data.createdAt,\n            lastAccessedAt: data.lastAccessedAt,\n            expiresAt: data.expiresAt,\n            ipAddress: data.ipAddress,\n            userAgent: data.userAgent,\n            metadata: data.metadata\n          }\n        ]\n      })\n    } catch (error) {\n      throw new Error(`Failed to set session: ${error}`)\n    }\n  }\n\n  /**\n   * Delete a session\n   */\n  async delete(sessionId: string): Promise<boolean> {\n    try {\n      const response = await this.request(\n        'POST',\n        `/tables/${this.tableName}/delete`,\n        {\n          filter: { sessionId }\n        }\n      )\n\n      return response.deletedCount > 0\n    } catch (error) {\n      console.error('Failed to delete session:', error)\n      return false\n    }\n  }\n\n  /**\n   * Check if a session exists\n   */\n  async exists(sessionId: string): Promise<boolean> {\n    const session = await this.get(sessionId)\n    return session !== null\n  }\n\n  /**\n   * Get all sessions for a user\n   */\n  async getByUserId(userId: string): Promise<Map<string, SessionData>> {\n    try {\n      const response = await this.request(\n        'POST',\n        `/tables/${this.tableName}/query`,\n        {\n          filter: { userId }\n        }\n      )\n\n      const result = new Map<string, SessionData>()\n\n      if (response.rows) {\n        for (const row of response.rows) {\n          result.set(row.sessionId, {\n            userId: row.userId,\n            data: row.data,\n            createdAt: row.createdAt,\n            lastAccessedAt: row.lastAccessedAt,\n            expiresAt: row.expiresAt,\n            ipAddress: row.ipAddress,\n            userAgent: row.userAgent,\n            metadata: row.metadata\n          })\n        }\n      }\n\n      return result\n    } catch (error) {\n      console.error('Failed to get sessions by user ID:', error)\n      return new Map()\n    }\n  }\n\n  /**\n   * Delete all sessions for a user\n   */\n  async deleteByUserId(userId: string): Promise<number> {\n    try {\n      const response = await this.request(\n        'POST',\n        `/tables/${this.tableName}/delete`,\n        {\n          filter: { userId }\n        }\n      )\n\n      return response.deletedCount || 0\n    } catch (error) {\n      console.error('Failed to delete sessions by user ID:', error)\n      return 0\n    }\n  }\n\n  /**\n   * Get all session IDs\n   */\n  async getAllSessionIds(): Promise<string[]> {\n    try {\n      const response = await this.request(\n        'POST',\n        `/tables/${this.tableName}/query`,\n        {\n          select: ['sessionId']\n        }\n      )\n\n      if (!response.rows) {\n        return []\n      }\n\n      return response.rows.map((row: any) => row.sessionId)\n    } catch (error) {\n      console.error('Failed to get all session IDs:', error)\n      return []\n    }\n  }\n\n  /**\n   * Remove expired sessions\n   */\n  async cleanup(): Promise<number> {\n    try {\n      const now = Date.now()\n\n      const response = await this.request(\n        'POST',\n        `/tables/${this.tableName}/delete`,\n        {\n          filter: {\n            expiresAt: { $lte: now }\n          }\n        }\n      )\n\n      return response.deletedCount || 0\n    } catch (error) {\n      console.error('Failed to cleanup expired sessions:', error)\n      return 0\n    }\n  }\n\n  /**\n   * Get session statistics\n   */\n  async getStats(): Promise<SessionStats> {\n    try {\n      const response = await this.request(\n        'POST',\n        `/tables/${this.tableName}/query`,\n        {}\n      )\n\n      const now = Date.now()\n      let activeSessions = 0\n      let expiredSessions = 0\n      let totalDuration = 0\n      const sessionsByUser: Record<string, number> = {}\n\n      if (response.rows) {\n        for (const row of response.rows) {\n          if (row.expiresAt > now) {\n            activeSessions++\n          } else {\n            expiredSessions++\n          }\n\n          // Track sessions by user\n          sessionsByUser[row.userId] = (sessionsByUser[row.userId] || 0) + 1\n\n          // Calculate duration\n          const duration = row.lastAccessedAt - row.createdAt\n          totalDuration += duration\n        }\n      }\n\n      const totalSessions = response.rows ? response.rows.length : 0\n      const averageDuration = totalSessions > 0 ? totalDuration / totalSessions : 0\n\n      return {\n        totalSessions,\n        activeSessions,\n        expiredSessions,\n        sessionsByUser,\n        averageDuration\n      }\n    } catch (error) {\n      console.error('Failed to get session stats:', error)\n      return {\n        totalSessions: 0,\n        activeSessions: 0,\n        expiredSessions: 0\n      }\n    }\n  }\n\n  /**\n   * Acquire a lock for a session\n   * Note: ZeroDB doesn't natively support locks, so we use a separate locks table\n   */\n  async acquireLock(sessionId: string, timeout: number): Promise<boolean> {\n    try {\n      const now = Date.now()\n      const expiresAt = now + timeout\n\n      // Try to insert lock\n      await this.request('POST', `/tables/session_locks/upsert`, {\n        rows: [\n          {\n            sessionId,\n            expiresAt,\n            createdAt: now\n          }\n        ]\n      })\n\n      return true\n    } catch (error) {\n      // Lock might already exist\n      return false\n    }\n  }\n\n  /**\n   * Release a lock for a session\n   */\n  async releaseLock(sessionId: string): Promise<void> {\n    try {\n      await this.request('POST', `/tables/session_locks/delete`, {\n        filter: { sessionId }\n      })\n    } catch (error) {\n      console.error('Failed to release lock:', error)\n    }\n  }\n\n  /**\n   * Close the store connection\n   */\n  async close(): Promise<void> {\n    // No persistent connection to close\n  }\n}\n","/**\n * Session Manager - Comprehensive session management for AI applications\n * Supports multiple storage backends, expiration strategies, and security features\n */\n\nimport { createHash, createCipheriv, createDecipheriv, randomBytes } from 'crypto'\nimport { generateId } from '../utils/id'\nimport { InMemorySessionStore } from './InMemorySessionStore'\nimport { RedisSessionStore } from './RedisSessionStore'\nimport { ZeroDBSessionStore } from './ZeroDBSessionStore'\nimport {\n  SessionConfig,\n  SessionStore,\n  Session,\n  SessionData,\n  CreateSessionOptions,\n  UpdateSessionOptions,\n  RefreshSessionOptions,\n  ListSessionsOptions,\n  SessionStats,\n  ExpirationStrategy,\n  SessionEvent,\n  SessionEventPayload\n} from './types'\n\n/**\n * Event listener for session events\n */\ntype SessionEventListener = (payload: SessionEventPayload) => void\n\n/**\n * SessionManager - Main class for managing user sessions\n */\nexport class SessionManager {\n  private store: SessionStore\n  private defaultTTL: number\n  private expirationStrategy: ExpirationStrategy\n  private encryptData: boolean\n  private encryptionKey?: Buffer\n  private maxSessionsPerUser: number\n  private enableLocking: boolean\n  private lockTimeout: number\n  private cleanupInterval?: NodeJS.Timeout\n  private eventListeners: Map<SessionEvent, Set<SessionEventListener>>\n\n  constructor(config: SessionConfig) {\n    this.defaultTTL = config.ttl || 3600 // Default: 1 hour\n    this.expirationStrategy = config.expirationStrategy || ExpirationStrategy.SLIDING\n    this.encryptData = config.encryptData || false\n    this.maxSessionsPerUser = config.maxSessionsPerUser || 0 // 0 = unlimited\n    this.enableLocking = config.enableLocking || false\n    this.lockTimeout = config.lockTimeout || 5000\n    this.eventListeners = new Map()\n\n    // Validate encryption configuration\n    if (this.encryptData && !config.encryptionKey) {\n      throw new Error('encryptionKey is required when encryptData is enabled')\n    }\n\n    if (this.encryptData && config.encryptionKey) {\n      // Derive encryption key from provided key\n      this.encryptionKey = createHash('sha256')\n        .update(config.encryptionKey)\n        .digest()\n    }\n\n    // Initialize store based on configuration\n    this.store = this.createStore(config)\n\n    // Set up automatic cleanup if enabled\n    if (config.autoCleanup !== false) {\n      const interval = config.cleanupInterval || 300000 // Default: 5 minutes\n      this.cleanupInterval = setInterval(() => {\n        this.cleanup().catch(error => {\n          console.error('Session cleanup error:', error)\n        })\n      }, interval)\n    }\n  }\n\n  /**\n   * Create the appropriate store based on configuration\n   */\n  private createStore(config: SessionConfig): SessionStore {\n    switch (config.type) {\n      case 'memory':\n        return new InMemorySessionStore(config.maxSessions)\n\n      case 'redis':\n        return new RedisSessionStore(config)\n\n      case 'zerodb':\n        const store = new ZeroDBSessionStore(config)\n        // Initialize ZeroDB table\n        store.initialize().catch(error => {\n          console.error('Failed to initialize ZeroDB store:', error)\n        })\n        return store\n\n      default:\n        throw new Error(`Unsupported store type: ${(config as any).type}`)\n    }\n  }\n\n  /**\n   * Create a new session\n   */\n  async create(\n    userId: string,\n    data: Record<string, any> = {},\n    options: CreateSessionOptions = {}\n  ): Promise<Session> {\n    // Check max sessions per user\n    if (this.maxSessionsPerUser > 0) {\n      const userSessions = await this.store.getByUserId(userId)\n      if (userSessions.size >= this.maxSessionsPerUser) {\n        // Delete oldest session\n        const sessions = Array.from(userSessions.entries())\n        sessions.sort((a, b) => a[1].createdAt - b[1].createdAt)\n        const oldestSession = sessions[0]\n        if (oldestSession) {\n          const oldestSessionId = oldestSession[0]\n          await this.delete(oldestSessionId)\n        }\n      }\n    }\n\n    // Generate session ID\n    const sessionId = generateId('sess')\n\n    // Calculate expiration\n    const now = Date.now()\n    const ttl = options.ttl || this.defaultTTL\n    const expiresAt = now + (ttl * 1000)\n\n    // Encrypt data if enabled\n    const sessionData: SessionData = {\n      userId,\n      data: this.encryptData ? this.encrypt(data) : data,\n      createdAt: now,\n      lastAccessedAt: now,\n      expiresAt,\n      ipAddress: options.ipAddress,\n      userAgent: options.userAgent,\n      metadata: options.metadata\n    }\n\n    // Store session\n    await this.store.set(sessionId, sessionData)\n\n    // Emit event\n    this.emit(SessionEvent.CREATED, {\n      sessionId,\n      userId,\n      event: SessionEvent.CREATED,\n      timestamp: now\n    })\n\n    // Return session\n    return this.toSession(sessionId, sessionData)\n  }\n\n  /**\n   * Get a session by ID\n   */\n  async get(sessionId: string): Promise<Session | null> {\n    const sessionData = await this.store.get(sessionId)\n    if (!sessionData) {\n      return null\n    }\n\n    // Check if expired\n    if (sessionData.expiresAt <= Date.now()) {\n      await this.delete(sessionId)\n      this.emit(SessionEvent.EXPIRED, {\n        sessionId,\n        userId: sessionData.userId,\n        event: SessionEvent.EXPIRED,\n        timestamp: Date.now()\n      })\n      return null\n    }\n\n    // Update last accessed time for sliding expiration\n    if (this.expirationStrategy === ExpirationStrategy.SLIDING ||\n        this.expirationStrategy === ExpirationStrategy.HYBRID) {\n      sessionData.lastAccessedAt = Date.now()\n\n      // Extend expiration for sliding strategy\n      if (this.expirationStrategy === ExpirationStrategy.SLIDING) {\n        sessionData.expiresAt = Date.now() + (this.defaultTTL * 1000)\n      }\n\n      await this.store.set(sessionId, sessionData)\n    }\n\n    return this.toSession(sessionId, sessionData)\n  }\n\n  /**\n   * Update a session's data\n   */\n  async update(\n    sessionId: string,\n    data: Record<string, any>,\n    options: UpdateSessionOptions = {}\n  ): Promise<Session | null> {\n    // Acquire lock if enabled\n    if (this.enableLocking) {\n      const locked = await this.acquireLock(sessionId)\n      if (!locked) {\n        throw new Error(`Failed to acquire lock for session ${sessionId}`)\n      }\n    }\n\n    try {\n      const sessionData = await this.store.get(sessionId)\n      if (!sessionData) {\n        return null\n      }\n\n      // Check if expired\n      if (sessionData.expiresAt <= Date.now()) {\n        await this.delete(sessionId)\n        return null\n      }\n\n      // Merge or replace data\n      if (options.merge) {\n        const existingData = this.encryptData ? this.decrypt(sessionData.data) : sessionData.data\n        const mergedData = { ...existingData, ...data }\n        sessionData.data = this.encryptData ? this.encrypt(mergedData) : mergedData\n      } else {\n        sessionData.data = this.encryptData ? this.encrypt(data) : data\n      }\n\n      // Update last accessed time\n      if (options.updateLastAccessed !== false) {\n        sessionData.lastAccessedAt = Date.now()\n\n        // Extend expiration for sliding strategy\n        if (this.expirationStrategy === ExpirationStrategy.SLIDING) {\n          sessionData.expiresAt = Date.now() + (this.defaultTTL * 1000)\n        }\n      }\n\n      // Store updated session\n      await this.store.set(sessionId, sessionData)\n\n      // Emit event\n      this.emit(SessionEvent.UPDATED, {\n        sessionId,\n        userId: sessionData.userId,\n        event: SessionEvent.UPDATED,\n        timestamp: Date.now()\n      })\n\n      return this.toSession(sessionId, sessionData)\n    } finally {\n      // Release lock\n      if (this.enableLocking) {\n        await this.releaseLock(sessionId)\n      }\n    }\n  }\n\n  /**\n   * Delete a session\n   */\n  async delete(sessionId: string): Promise<boolean> {\n    const sessionData = await this.store.get(sessionId)\n    const deleted = await this.store.delete(sessionId)\n\n    if (deleted && sessionData) {\n      this.emit(SessionEvent.DELETED, {\n        sessionId,\n        userId: sessionData.userId,\n        event: SessionEvent.DELETED,\n        timestamp: Date.now()\n      })\n    }\n\n    return deleted\n  }\n\n  /**\n   * Refresh/extend a session's expiration\n   */\n  async refresh(\n    sessionId: string,\n    options: RefreshSessionOptions = {}\n  ): Promise<Session | null> {\n    const sessionData = await this.store.get(sessionId)\n    if (!sessionData) {\n      return null\n    }\n\n    // Check if already expired\n    if (sessionData.expiresAt <= Date.now()) {\n      await this.delete(sessionId)\n      return null\n    }\n\n    // Extend expiration\n    const ttl = options.ttl || this.defaultTTL\n    sessionData.expiresAt = Date.now() + (ttl * 1000)\n    sessionData.lastAccessedAt = Date.now()\n\n    await this.store.set(sessionId, sessionData)\n\n    // Emit event\n    this.emit(SessionEvent.REFRESHED, {\n      sessionId,\n      userId: sessionData.userId,\n      event: SessionEvent.REFRESHED,\n      timestamp: Date.now()\n    })\n\n    return this.toSession(sessionId, sessionData)\n  }\n\n  /**\n   * Get all sessions for a user\n   */\n  async getUserSessions(userId: string): Promise<Session[]> {\n    const sessionsMap = await this.store.getByUserId(userId)\n    const sessions: Session[] = []\n    const now = Date.now()\n\n    Array.from(sessionsMap.entries()).forEach(([sessionId, sessionData]) => {\n      // Skip expired sessions\n      if (sessionData.expiresAt > now) {\n        sessions.push(this.toSession(sessionId, sessionData))\n      }\n    })\n\n    return sessions\n  }\n\n  /**\n   * Delete all sessions for a user\n   */\n  async deleteUserSessions(userId: string): Promise<number> {\n    return await this.store.deleteByUserId(userId)\n  }\n\n  /**\n   * List sessions with optional filters\n   */\n  async list(options: ListSessionsOptions = {}): Promise<Session[]> {\n    const sessionIds = await this.store.getAllSessionIds()\n    const sessions: Session[] = []\n    const now = Date.now()\n\n    const limit = options.limit || 100\n    const offset = options.offset || 0\n    let count = 0\n    let skipped = 0\n\n    for (const sessionId of sessionIds) {\n      if (count >= limit) {\n        break\n      }\n\n      const sessionData = await this.store.get(sessionId)\n      if (!sessionData) {\n        continue\n      }\n\n      // Filter expired sessions\n      const isExpired = sessionData.expiresAt <= now\n      if (isExpired && !options.includeExpired) {\n        continue\n      }\n\n      // Handle offset\n      if (skipped < offset) {\n        skipped++\n        continue\n      }\n\n      sessions.push(this.toSession(sessionId, sessionData))\n      count++\n    }\n\n    return sessions\n  }\n\n  /**\n   * Validate if a session is active\n   */\n  async validate(sessionId: string): Promise<boolean> {\n    const session = await this.get(sessionId)\n    return session !== null && !session.isExpired\n  }\n\n  /**\n   * Clean up expired sessions\n   */\n  async cleanup(): Promise<number> {\n    return await this.store.cleanup()\n  }\n\n  /**\n   * Get session statistics\n   */\n  async getStats(): Promise<SessionStats> {\n    return await this.store.getStats()\n  }\n\n  /**\n   * Acquire a lock for a session\n   */\n  private async acquireLock(sessionId: string): Promise<boolean> {\n    if (!this.store.acquireLock) {\n      return true\n    }\n\n    const locked = await this.store.acquireLock(sessionId, this.lockTimeout)\n\n    if (locked) {\n      this.emit(SessionEvent.LOCKED, {\n        sessionId,\n        userId: '',\n        event: SessionEvent.LOCKED,\n        timestamp: Date.now()\n      })\n    }\n\n    return locked\n  }\n\n  /**\n   * Release a lock for a session\n   */\n  private async releaseLock(sessionId: string): Promise<void> {\n    if (!this.store.releaseLock) {\n      return\n    }\n\n    await this.store.releaseLock(sessionId)\n\n    this.emit(SessionEvent.UNLOCKED, {\n      sessionId,\n      userId: '',\n      event: SessionEvent.UNLOCKED,\n      timestamp: Date.now()\n    })\n  }\n\n  /**\n   * Convert SessionData to Session object\n   */\n  private toSession(sessionId: string, sessionData: SessionData): Session {\n    const now = Date.now()\n\n    return {\n      sessionId,\n      userId: sessionData.userId,\n      data: this.encryptData ? this.decrypt(sessionData.data) : sessionData.data,\n      createdAt: sessionData.createdAt,\n      lastAccessedAt: sessionData.lastAccessedAt,\n      expiresAt: sessionData.expiresAt,\n      isExpired: sessionData.expiresAt <= now,\n      ipAddress: sessionData.ipAddress,\n      userAgent: sessionData.userAgent,\n      metadata: sessionData.metadata\n    }\n  }\n\n  /**\n   * Encrypt session data\n   */\n  private encrypt(data: Record<string, any>): any {\n    if (!this.encryptionKey) {\n      return data\n    }\n\n    const json = JSON.stringify(data)\n    const iv = randomBytes(16)\n    const cipher = createCipheriv('aes-256-cbc', this.encryptionKey, iv)\n\n    let encrypted = cipher.update(json, 'utf8', 'hex')\n    encrypted += cipher.final('hex')\n\n    return {\n      encrypted: true,\n      iv: iv.toString('hex'),\n      data: encrypted\n    }\n  }\n\n  /**\n   * Decrypt session data\n   */\n  private decrypt(data: any): Record<string, any> {\n    if (!data || !data.encrypted || !this.encryptionKey) {\n      return data\n    }\n\n    const iv = Buffer.from(data.iv, 'hex')\n    const decipher = createDecipheriv('aes-256-cbc', this.encryptionKey, iv)\n\n    let decrypted = decipher.update(data.data, 'hex', 'utf8')\n    decrypted += decipher.final('utf8')\n\n    return JSON.parse(decrypted)\n  }\n\n  /**\n   * Register an event listener\n   */\n  on(event: SessionEvent, listener: SessionEventListener): void {\n    const listeners = this.eventListeners.get(event) || new Set()\n    listeners.add(listener)\n    this.eventListeners.set(event, listeners)\n  }\n\n  /**\n   * Remove an event listener\n   */\n  off(event: SessionEvent, listener: SessionEventListener): void {\n    const listeners = this.eventListeners.get(event)\n    if (listeners) {\n      listeners.delete(listener)\n    }\n  }\n\n  /**\n   * Emit a session event\n   */\n  private emit(event: SessionEvent, payload: SessionEventPayload): void {\n    const listeners = this.eventListeners.get(event)\n    if (listeners) {\n      Array.from(listeners).forEach(listener => {\n        try {\n          listener(payload)\n        } catch (error) {\n          console.error('Error in session event listener:', error)\n        }\n      })\n    }\n  }\n\n  /**\n   * Close the session manager and cleanup resources\n   */\n  async close(): Promise<void> {\n    // Clear cleanup interval\n    if (this.cleanupInterval) {\n      clearInterval(this.cleanupInterval)\n    }\n\n    // Close store connection\n    if (this.store.close) {\n      await this.store.close()\n    }\n\n    // Clear event listeners\n    this.eventListeners.clear()\n  }\n}\n"]}