Skip to content

Typesense Utilities ​

Overview ​

Utility functions and classes for Typesense search integration. Provides connection management, error handling, and search operations.

File Information ​

  • Path: server/api/typesense/utils.ts
  • Purpose: Typesense client configuration and utility functions
  • Dependencies: typesense, axios, h3

Typesense Client ​

Client Configuration ​

The Typesense client is configured with environment variables:

typescript
const typesenseClient = new Typesense.Client({
  nodes: [{
    host: process.env.TYPESENSE_HOST!,
    port: parseInt(process.env.TYPESENSE_PORT!),
    protocol: process.env.TYPESENSE_PROTOCOL!,
  }],
  apiKey: process.env.TYPESENSE_API_KEY!,
  connectionTimeoutSeconds: parseInt(process.env.TYPESENSE_CONNECTION_TIMEOUT || '10', 10),
  retryIntervalSeconds: 0.1,
  numRetries: 3,
  healthcheckIntervalSeconds: 30,
})

Environment Variables:

  • TYPESENSE_HOST - Typesense server hostname
  • TYPESENSE_PORT - Typesense server port
  • TYPESENSE_PROTOCOL - Protocol (http/https)
  • TYPESENSE_API_KEY - API key for authentication
  • TYPESENSE_CONNECTION_TIMEOUT - Connection timeout in seconds (default: 10)

Error Handling ​

TypesenseConnectionError ​

Custom error class for Typesense connection issues:

typescript
export class TypesenseConnectionError extends Error {
  public originalError: any
  public status: number  // Always 503 (Service Unavailable)
}

When Thrown:

  • Connection refused errors (ECONNREFUSED)
  • Connection reset errors (ECONNRESET)
  • Timeout errors (ETIMEDOUT)
  • HTTP 502, 503, 504 status codes
  • Typesense service unavailable

Usage:

typescript
try {
  await performMultiSearch(searches, params)
} catch (error) {
  if (error instanceof TypesenseConnectionError) {
    // Handle connection error
    console.error('Typesense unavailable:', error.message)
  }
}

Functions ​

performMultiSearch ​

Performs multi-collection search across multiple Typesense collections.

Signature:

typescript
export const performMultiSearch = async (
  searchRequests: SearchRequest[],
  commonSearchParams: CommonSearchParams
): Promise<MultiSearchResponse>

Parameters:

SearchRequest:

typescript
interface SearchRequest {
  collection: string           // Collection name
  q: string                     // Search query
  filter_by?: string           // Filter expression
  sort_by?: string             // Sort expression
  include_fields?: string[]    // Fields to include
  group_by?: string            // Group by field
  group_limit?: number         // Group limit
  infix?: string               // Infix search
  prefix?: boolean             // Prefix search
  num_typos?: number           // Number of typos allowed
  typo_tokens_threshold?: number // Typo threshold
}

CommonSearchParams:

typescript
interface CommonSearchParams {
  query_by: string             // Fields to search
  per_page: number             // Results per page
  page: number                 // Page number
  sort_by?: string             // Default sort expression
}

Returns:

  • MultiSearchResponse - Response from Typesense multi-search

Error Handling:

  • Throws TypesenseConnectionError for connection issues
  • Throws Error for Typesense API errors
  • Handles HTTP response errors (502, 503, 504)

Usage:

typescript
const searches = [
  {
    collection: 'assets',
    q: 'logo',
    filter_by: 'type:image',
    sort_by: 'created_at:desc'
  },
  {
    collection: 'folders',
    q: 'brand',
    filter_by: 'status:active'
  }
]

const commonParams = {
  query_by: 'name,description',
  per_page: 20,
  page: 1
}

const results = await performMultiSearch(searches, commonParams)

verifyUserToken ​

Verifies user authentication token and workspace access.

Signature:

typescript
export const verifyUserToken = async (
  token: string,
  workspaceId?: string
): Promise<string | number>

Parameters:

  • token: string - Authentication token
  • workspaceId?: string - Optional workspace ID to verify access

Returns:

  • string - Workspace unique ID if user has access
  • number - 0 if user doesn't have access or workspace not found

Throws:

  • createError({ statusCode: 401 }) - If token is invalid or unauthorized

Usage:

typescript
try {
  const workspaceUniqueId = await verifyUserToken(token, workspaceId)
  if (workspaceUniqueId) {
    // User has access to workspace
    console.log('Workspace ID:', workspaceUniqueId)
  } else {
    // User doesn't have access
    console.log('Access denied')
  }
} catch (error) {
  // Token invalid or unauthorized
  console.error('Token verification failed')
}

Error Handling Patterns ​

Connection Errors ​

typescript
try {
  await performMultiSearch(searches, params)
} catch (error: any) {
  if (error.code === 'ECONNREFUSED' || 
      error.code === 'ECONNRESET' || 
      error.code === 'ETIMEDOUT') {
    throw new TypesenseConnectionError(
      'Unable to connect to Typesense server',
      error
    )
  }
}

Typesense API Errors ​

typescript
try {
  await performMultiSearch(searches, params)
} catch (error: any) {
  if (error.name === 'TypesenseError' || 
      error.name === 'RequestError' || 
      error.name === 'ServerError') {
    if (error.message.includes('connection') || 
        error.message.includes('timeout')) {
      throw new TypesenseConnectionError(
        'Failed to establish connection with Typesense',
        error
      )
    }
    throw new Error(`Typesense Error: ${error.message}`)
  }
}

HTTP Response Errors ​

typescript
try {
  await performMultiSearch(searches, params)
} catch (error: any) {
  if (error.response) {
    if ([502, 503, 504].includes(error.response.status)) {
      throw new TypesenseConnectionError(
        'Typesense service is temporarily unavailable',
        error
      )
    }
    throw new Error(
      `Typesense Error: ${error.response.data.message || 'Unknown error'}`
    )
  }
}

Best Practices ​

  1. Error Handling: Always handle TypesenseConnectionError separately from other errors
  2. Retry Logic: The client includes built-in retry logic (3 retries with 0.1s interval)
  3. Connection Timeout: Configure appropriate timeout based on network conditions
  4. Health Checks: Client performs health checks every 30 seconds
  5. Token Verification: Always verify user tokens before performing searches
  6. Workspace Access: Check workspace access before allowing search operations