@storehouse/redis-om - v1.0.0
    Preparing search index...

    @storehouse/redis-om - v1.0.0

    @storehouse/redis-om

    Redis-OM manager adapter for @storehouse/core. Provides seamless integration with Redis using the Redis-OM object mapping library.

    • Type-safe Redis operations with Redis-OM object mapping
    • Schema-based models for structured data storage
    • Full-text search support with RediSearch
    • Connection lifecycle management with automatic reconnection
    • Health check utilities for monitoring
    • Multi-manager support via Storehouse registry
    • Redis server with RediSearch and RedisJSON modules (for search functionality)
    • Node.js 16 or higher
    npm install @storehouse/core redis redis-om @storehouse/redis-om
    

    Create Redis-OM schemas to define your data structures:

    schemas/movie.ts

    import { Schema } from 'redis-om'

    export const movieSchema = new Schema('movies', {
    title: { type: 'string' },
    director: { type: 'string' },
    year: { type: 'number' },
    rating: { type: 'number' },
    genres: { type: 'string[]' }
    })

    index.ts

    import { Storehouse } from '@storehouse/core';
    import { RedisOMManager } from '@storehouse/redis-om';
    import { movieSchema } from './schemas/movie';

    // Register the manager
    Storehouse.add({
    redis: {
    type: RedisOMManager,
    config: {
    // Redis client connection options
    options: {
    socket: {
    host: 'localhost',
    port: 6379
    }
    },
    // Register your schemas
    models: [movieSchema]
    }
    }
    });
    import { Storehouse } from '@storehouse/core';
    import { RedisOMManager } from '@storehouse/redis-om';
    import { Repository } from 'redis-om';
    import { RedisClientType } from 'redis';

    // Get the manager
    const manager = Storehouse.getManager<RedisOMManager>('redis');

    if (manager) {
    // Connect to Redis
    await manager.connect();

    // Create search indexes (required for Repository#search)
    await manager.createIndexes();

    // Get a repository
    const moviesRepo = manager.getModel('movies');

    if (moviesRepo) {
    // Create a new movie
    const movie = await moviesRepo.save({
    title: 'Inception',
    director: 'Christopher Nolan',
    year: 2010,
    rating: 8.8,
    genres: ['Sci-Fi', 'Thriller']
    });

    console.log('Created movie:', movie);

    // Search for movies
    const sciFiMovies = await moviesRepo
    .search()
    .where('genres').contains('Sci-Fi')
    .return.all();

    console.log('Sci-Fi movies:', sciFiMovies.length);

    // Get total count
    const count = await moviesRepo.search().return.count();
    console.log('Total movies:', count);
    }
    }

    The package provides helper functions that throw errors instead of returning undefined, making your code cleaner and safer.

    Retrieves a RedisOMManager instance from the registry.

    import { Storehouse } from '@storehouse/core';
    import { getManager } from '@storehouse/redis-om';

    const manager = getManager(Storehouse, 'redis');
    await manager.connect();

    Throws:

    • ManagerNotFoundError - If the manager doesn't exist
    • InvalidManagerConfigError - If the manager is not a RedisOMManager instance

    Retrieves the underlying Redis client connection.

    import { Storehouse } from '@storehouse/core';
    import { getConnection } from '@storehouse/redis-om';

    const client = getConnection(Storehouse, 'redis');

    // Use Redis client directly
    await client.set('key', 'value');
    const value = await client.get('key');

    Throws:

    • ManagerNotFoundError - If the manager doesn't exist

    Retrieves a Redis-OM Repository by name.

    import { Storehouse } from '@storehouse/core';
    import { getModel } from '@storehouse/redis-om';

    // Get model from default manager
    const movies = getModel(Storehouse, 'movies');

    // Get model from specific manager
    const users = getModel(Storehouse, 'redis', 'users');

    // Use the repository
    await movies.createIndex();
    const count = await movies.search().return.count();

    Throws:

    • ModelNotFoundError - If the model doesn't exist

    Establishes connection to Redis.

    await manager.connect();
    

    Closes the Redis connection gracefully using QUIT command.

    await manager.close();
    

    Returns the underlying Redis client instance.

    const client = manager.getConnection();
    await client.ping();

    Retrieves a registered repository by schema name.

    const moviesRepo = manager.getModel('movies');
    

    Creates search indexes for all registered repositories. Required for using Repository#search().

    Requires: RediSearch and RedisJSON modules installed on Redis.

    await manager.createIndexes();
    

    Removes all existing indexes. Useful when schemas change.

    Requires: RediSearch and RedisJSON modules installed on Redis.

    await manager.dropIndexes();
    await manager.createIndexes(); // Recreate with updated schemas

    Checks if the connection is currently active.

    const connected = await manager.isConnected();
    if (connected) {
    console.log('Redis is connected');
    }

    Performs a comprehensive health check including ping test and latency measurement.

    const health = await manager.healthCheck();

    if (health.healthy) {
    console.log(`✓ Redis is healthy`);
    console.log(` Latency: ${health.details.latency}`);
    console.log(` Models: ${health.details.models?.join(', ')}`);
    console.log(` Ping: ${health.details.pingResponse}`);
    } else {
    console.error(`✗ Redis is unhealthy: ${health.message}`);
    }

    The health check returns a detailed result object with the following structure:

    • healthy: boolean - Overall health status
    • message: string - Descriptive message about the health status
    • timestamp: number - Timestamp when the health check was performed
    • latency?: number - Response time in milliseconds
    • details: object - Detailed connection information
      • name: string - Manager name
      • isOpen: boolean - Connection open status
      • isReady: boolean - Connection ready status
      • pingResponse?: string | Buffer - Redis PING response
      • models?: string[] - Registered model names
      • latency?: string - Response time in ms
      • error?: string - Error details (if unhealthy)

    You can register multiple Redis connections:

    Storehouse.add({
    cache: {
    type: RedisOMManager,
    config: {
    options: { url: 'redis://localhost:6379' },
    models: [sessionSchema]
    }
    },
    queue: {
    type: RedisOMManager,
    config: {
    options: { url: 'redis://localhost:6380' },
    models: [jobSchema]
    }
    }
    });

    // Access specific managers
    const cacheManager = getManager(Storehouse, 'cache');
    const queueManager = getManager(Storehouse, 'queue');

    Set the manager type to simplify configuration and use string identifiers instead of class references:

    import { Storehouse } from '@storehouse/core';
    import { RedisOMManager } from '@storehouse/redis-om';

    // Set default manager type
    Storehouse.setManagerType(RedisOMManager);

    // Now you can use type string instead of class
    Storehouse.add({
    redis: {
    type: '@storehouse/redis-om',
    config: {
    options: { url: 'redis://localhost:6379' },
    models: [movieSchema]
    }
    }
    });

    Access the Redis client directly for advanced operations beyond what Redis-OM provides:

    const client = getConnection(Storehouse, 'redis');

    // Use Redis commands directly
    await client.hSet('user:1000', {
    name: 'John',
    email: 'john@example.com'
    });

    const user = await client.hGetAll('user:1000');

    The manager automatically logs connection lifecycle events. These are logged using the @novice1/logger package and can be enabled with Debug mode:

    import { Debug } from '@novice1/logger';

    Debug.enable('@storehouse/redis-om*');

    Events logged:

    • error - Connection errors
    • connect - Connection initiated
    • ready - Connection established
    • end - Connection closed
    • reconnecting - Reconnection attempt

    The package is written in TypeScript and provides full type definitions for type-safe operations:

    import { RedisClientType } from 'redis';
    import { Repository } from 'redis-om';
    import { RedisOMManager, RedisOMHealthCheckResult } from '@storehouse/redis-om';

    // Typed manager
    const manager = getManager<RedisOMManager>(Storehouse, 'redis');

    // Typed connection
    const client: RedisClientType = getConnection(Storehouse, 'redis');

    // Typed model
    const movies = getModel<{
    title: string;
    director: string;
    year: number;
    rating: number;
    genres: string[]
    }>(Storehouse, 'movies');

    All helper functions throw specific errors for better error handling:

    • ManagerNotFoundError - When a manager is not found in the registry
    • ModelNotFoundError - When a model is not found
    • InvalidManagerConfigError - When a manager is not of the expected type
    import {
    getManager,
    getModel,
    getConnection
    } from '@storehouse/redis-om';
    import {
    ManagerNotFoundError,
    ModelNotFoundError,
    InvalidManagerConfigError
    } from '@storehouse/core';

    try {
    const manager = getManager(Storehouse, 'nonexistent');
    } catch (error) {
    if (error instanceof ManagerNotFoundError) {
    console.error('Manager not found:', error.message);
    } else if (error instanceof InvalidManagerConfigError) {
    console.error('Invalid manager type:', error.message);
    }
    }

    try {
    const model = getModel(Storehouse, 'nonexistent');
    } catch (error) {
    if (error instanceof ModelNotFoundError) {
    console.error('Model not found:', error.message);
    }
    }
    1. Always create indexes - Call createIndexes() after connecting to enable search functionality
    2. Use health checks - Monitor connection health in production environments
    3. Handle disconnections - Implement reconnection and retry logic for critical operations
    4. Close connections - Always call close() when shutting down your application
    5. Schema versioning - Use dropIndexes() then createIndexes() when updating schemas

    MIT