typesense-js Documentation

repository·master·Indexed 20 days ago

https://github.com/typesense/typesense-js

A JavaScript client library for accessing the Typesense HTTP API, compatible with both Node.js and browser environments. It provides a `Client` class for administrative tasks (managing collections, documents, and synonyms) and a `SearchClient` optimized for read-only search operations. The library supports AbortSignals for per-request timeouts, custom HTTP configuration via Axios adapters, and streaming responses for AI-driven features.

Tokens
14.5K
Snippets
47
Records
65
Agent score
67%

What's inside typesense-js

  1. Integrations: GatsbyJS, Firebase, and UI Components

    master

    Typesense provides several ecosystem integrations:

  2. Include typesense-js in the browser via CDN

    master

    For direct browser usage without a build step, you can include the minified JS file using a <script> tag. You can host it locally from your dist folder or use jsDelivr.

    Local file:

    <script src="dist/typesense.min.js"></script>

    jsDelivr:

    <script src="https://cdn.jsdelivr.net/npm/typesense@3/dist/typesense.min.js"></script>
  3. Install typesense-js via npm

    master

    To use the Typesense client in a Node.js or server-side environment, install the typesense package. It is also recommended to install @babel/runtime as a direct peer dependency to avoid duplicate instances in your bundle.

    npm install --save typesense
    npm install --save @babel/runtime
  4. Use Client and SearchClient for different operations

    master

    The library separates concerns into two main client types:

    • Client: Used for management operations such as creating/deleting collections, managing documents, configuring synonyms, curation sets, and analytics rules.
    • SearchClient: Optimized for performing search queries and multi-search operations.
  5. Access specific resources via the Client

    master

    The Client class uses a hierarchical pattern to access different Typesense resources. Most resource methods follow a consistent pattern:

    1. Calling without an identifier: Calling the method without arguments (e.g., client.collections()) returns a manager object used for operations on all resources of that type (e.g., listing all collections).
    2. Calling with an identifier: Calling the method with a specific name or ID (e.g., client.collections('my_collection')) returns a specific resource instance for that single entity, allowing you to perform operations directly on it.

    Supported resource accessors include:

    • collections(collectionName?)
    • aliases(aliasName?)
    • keys(id?)
    • presets(id?)
    • stopwords(id?)
    • conversations(id?)
    • nlSearchModels(id?)
    • synonymSets(synonymSetName?)
    • curationSets(name?)
    // Access the manager for all collections
    const collectionsManager = client.collections();
    
    // Access a specific collection instance
    const myCollection = client.collections('products');
    
    // Access the manager for all aliases
    const aliasesManager = client.aliases();
    
    // Access a specific alias instance
    const myAlias = client.aliases('search_alias');
  6. Configure streaming search responses

    master

    When working with streaming responses (e.g., for AI-generated content or large datasets), you can provide a StreamConfig to handle data chunks, errors, and completion events.

    • onChunk: Triggered for every piece of data received.
    • onError: Triggered if the stream encounters an error.
    • onComplete: Triggered when the stream finishes successfully (includes the full SearchResponse).
    interface MyStreamConfig extends StreamConfig<MyDocumentSchema> {
      onChunk?: (data: { conversation_id: string; message: string }) => void;
      onError?: (error: Error) => void;
      onComplete?: (data: SearchResponse<MyDocumentSchema>) => void;
    }
  7. Understand SearchResponse structure

    master

    A SearchResponse<T> contains the results of a search query, including hits, facets, and metadata.

    Key Fields:

    • hits?: SearchResponseHit<T>[]: The actual search results.
    • found: number: Total number of documents matching the query.
    • out_of: number: Total number of documents in the collection.
    • facet_counts?: SearchResponseFacetCountSchema<T>[]: Aggregated counts for facets.
    • search_time_ms: number: Time taken to perform the search.
    • grouped_hits?: { group_key: string[]; hits: SearchResponseHit<T>[]; found?: number; }[]: Results grouped by a specific field.
    • parsed_nl_query?: Information if a Natural Language query was used, including generated_params and llm_response.
    export interface SearchResponse<T extends DocumentSchema> {
        facet_counts?: SearchResponseFacetCountSchema<T>[];
        found: number;
        found_docs?: number;
        out_of: number;
        page: number;
        request_params: SearchResponseRequestParams;
        search_time_ms: number;
        search_cutoff?: boolean;
        hits?: SearchResponseHit<T>[];
        grouped_hits?: {
            group_key: string[];
            hits: SearchResponseHit<T>[];
            found?: number;
        }[];
        parsed_nl_query?: {
            parse_time_ms: number;
            generated_params: SearchParams<T>;
            augmented_params: SearchParams<T>;
            llm_response?: LLMResponse;
        };
        conversation?: {
            answer: string;
            conversation_history: {
                conversation: object[];
                id: string;
                last_updated: number;
                ttl: number;
            };
            conversation_id: string;
            query: string;
        };
        error?: string;
        code?: number;
        metadata?: JsonRecord;
    }
  8. MultiSearchResponse types

    master

    Typesense supports multi-search requests, which can return results in two modes based on the union parameter:

    1. Standard Multi-Search: Returns an object with a results array where each index corresponds to the input search request. The response shape is { results: { [Index in keyof T]: SearchResponse<T[Index]> } & { length: T['length'] } }.
    2. Union Multi-Search: When union: true is used, the results are merged into a single response. The response shape is UnionSearchResponse<T>, which includes union_request_params to track individual request metadata.
  9. Execute multiple searches with MultiSearch

    master

    Typesense supports performing multiple searches in a single request using the MultiSearch API. This is useful for reducing network overhead when querying different collections or using different parameters simultaneously.

    There are two modes for MultiSearch:

    1. Standard MultiSearch: Returns an object containing a results array, where each element corresponds to the search result of the respective request.
    2. Union MultiSearch: When union: true is passed, it returns a UnionSearchResponse, which aggregates results into a single response structure.

    Use MultiSearchRequestsSchema to define the array of searches to be executed.

  10. Configure the Typesense Client

    master

    Initialize a new Typesense.Client by providing connection details and an API key. You can also set a global connectionTimeoutSeconds to apply a timeout to all requests made by that client instance.

    Security Note: When using the client in a browser, never use your master API key. Instead, use an API key that is restricted to search-only operations.

    const client = new Typesense.Client({
      nodes: [{ host: "localhost", port: "8108", protocol: "http" }],
      apiKey: "xyz",
      connectionTimeoutSeconds: 30, // 30 second timeout for all requests
    });
  11. Use AbortSignals for per-request timeouts

    master

    You can control individual request lifecycles using the standard Web AbortController API. This allows you to cancel specific requests or implement per-request timeouts without affecting the global client configuration.

    Note: The .import() operation does not support abort signals or timeout configurations.

    // Search with 5-second timeout
    const controller = new AbortController();
    setTimeout(() => controller.abort(), 5000);
    
    const results = await client.collections("books").documents().search(
      {
        q: "*",
        query_by: "title",
      },
      { abortSignal: controller.signal },
    );
    
    // Collections with 2-second timeout
    const collectionsController = new AbortController();
    setTimeout(() => collectionsController.abort(), 2000);
    
    const collections = await client.collections().retrieve({
      abortSignal: collectionsController.signal,
    });
  12. Configure the Typesense Client

    master

    To initialize a Typesense client, you must provide a ConfigurationOptions object. The most critical fields are apiKey and nodes.

    Nodes can be defined in three ways:

    1. Full Configuration: An array of objects containing host, port, and protocol.
    2. Hostname Configuration: An array of objects containing host, port, and protocol (useful for specific port management).
    3. URL Configuration: An array of objects containing a single url string.

    By default, randomizeNodes is set to true, meaning the client will shuffle the provided nodes to distribute requests. You can also specify a nearestNode to prioritize a specific server.

    import { Client } from 'typesense';
    
    const client = new Client({
      nodes: [
        {
          host: 'localhost',
          port: 8108,
          protocol: 'http:'
        }
      ],
      apiKey: 'xyz',
      // Optional settings
      connectionTimeoutSeconds: 2,
      numRetries: 3
    });