Package Exports
- @goatlab/typesense
- @goatlab/typesense/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@goatlab/typesense) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@goatlab/typesense
A modern, type-safe TypeScript wrapper for the Typesense search engine API. This package provides a comprehensive client with built-in resilience, multi-tenancy support, and a clean, grouped API interface.
Installation
npm install @goatlab/typesense
# or
pnpm add @goatlab/typesense
# or
yarn add @goatlab/typesenseBasic Usage
import { TypesenseApi } from '@goatlab/typesense'
// Initialize the client
const typesense = new TypesenseApi({
prefixUrl: 'http://localhost:8108',
token: 'your-api-key',
collectionName: 'products' // default collection name
})
// Create a collection
await typesense.collections.create({
name: 'products',
fields: [
{ name: 'id', type: 'string' },
{ name: 'title', type: 'string' },
{ name: 'price', type: 'float' },
{ name: 'description', type: 'string' }
]
})
// Insert a document
await typesense.documents.insert({
id: '1',
title: 'iPhone 15',
price: 999.99,
description: 'Latest Apple smartphone'
})
// Search documents
const results = await typesense.search.query({
q: 'iphone',
query_by: 'title,description'
})Key Features
- Grouped API Interface: Organized methods under logical namespaces (collections, documents, search, admin)
- Full Type Safety: Generic type support for document operations with compile-time checking
- Multi-tenancy Support: Built-in tenant isolation with automatic collection name prefixing
- Resilience Features: Circuit breaker pattern, rate limiting, and automatic retries
- Schema Management: Automatic schema caching and version compatibility checks
- Stream Support: Efficient document export with streaming capabilities
- Advanced Search: Support for text search, vector search, and multi-search operations
Available Methods
Collections
collections.create()- Create a new collectioncollections.get()- Retrieve collection detailscollections.update()- Update collection schemacollections.delete()- Delete a collectioncollections.list()- List all collectionscollections.getOrCreate()- Get existing or create new collection
Documents
documents.insert()- Insert a single documentdocuments.upsert()- Insert or update a documentdocuments.update()- Update an existing documentdocuments.delete()- Delete a document by IDdocuments.getById()- Retrieve a document by IDdocuments.import()- Bulk import documentsdocuments.export()- Export documents (with optional filtering)documents.exportStream()- Export documents as a streamdocuments.deleteByFilter()- Delete documents matching a filterdocuments.clear()- Clear all documents in a collection
Search
search.query()- Perform a search querysearch.text()- Text-based searchsearch.vector()- Vector similarity searchsearch.multi()- Execute multiple searches in one request
Admin
admin.health()- Check server healthadmin.waitForHealth()- Wait for server to be healthyadmin.getMetrics()- Get server metricsadmin.getStats()- Get server statisticsadmin.getCollectionStats()- Get collection-specific statistics
Additional Features (v29+)
- Aliases: Create and manage collection aliases
- Synonyms: Define search synonyms
- Overrides: Set up search result overrides
- Presets: Configure search presets
Type Safety
The TypesenseApi supports full type safety for document operations:
Basic Typed API
import { createTypedApi } from '@goatlab/typesense'
// Define your document type
interface Product {
id: string
title: string
price: number
inStock: boolean
}
// Create a typed API instance
const productApi = createTypedApi<Product>()({
prefixUrl: 'http://localhost:8108',
token: 'your-api-key',
collectionName: 'products'
})
// All document operations are now type-safe
await productApi.documents.insert({
id: '1',
title: 'Widget',
price: 99.99,
inStock: true
}) // ✅ Typed
// TypeScript will catch errors at compile time
// await productApi.documents.insert({ id: '2', title: 'Gadget' })
// ❌ Error: missing 'price' and 'inStock'Direct Generic Usage
const api = new TypesenseApi<Product>({
prefixUrl: 'http://localhost:8108',
token: 'your-api-key',
collectionName: 'products'
})Multi-tenancy
The TypesenseApi provides built-in multi-tenancy support through collection-level isolation:
Basic Tenant Setup
// Create API instance with tenant ID
const api = new TypesenseApi({
prefixUrl: 'http://localhost:8108',
token: 'your-api-key',
tenantId: 'acme', // Tenant ID
collectionName: 'products'
})
// All operations use tenant-prefixed collections automatically
// Collection name becomes: 'acme__products'
await api.documents.insert({ id: '1', name: 'Product' })Type-Safe Tenant APIs
import { forTenant } from '@goatlab/typesense'
interface Customer {
id: string
name: string
email: string
}
// Create tenant-specific APIs with compile-time safety
const tenant1Api = forTenant<Customer, 'tenant1'>('tenant1', {
prefixUrl: 'http://localhost:8108',
token: 'your-api-key',
collectionName: 'customers'
})
// Tenant ID is preserved in the type
const tenantId: 'tenant1' = tenant1Api.tenantId // ✅ Type-safeTenant Admin Operations
// List all collections for a tenant
const collections = await api.listTenantCollections()
// Returns: ['acme__products', 'acme__users', ...]
// Get base collection names (without prefix)
const baseNames = await api.listTenantBaseCollectionNames()
// Returns: ['products', 'users', ...]
// Check if a collection exists
const exists = await api.tenantCollectionExists('products')
// Delete all tenant collections (use with caution!)
await api.deleteAllTenantCollections()Collection Naming Convention
Tenant collections follow the pattern: <tenantId>__<baseCollectionName>
- Tenant IDs are automatically sanitized (lowercase, alphanumeric + hyphens/underscores)
- Maximum tenant ID length: 128 characters
- Examples:
acme__products,tenant-123__users
Schema-based Type Safety
The TypesenseApi provides compile-time type safety for your collections using TypeScript's advanced type system:
Define Collections with Type Inference
import { TypesenseApi } from '@goatlab/typesense'
// Define your collection schema with proper const assertions
const ProductCollection = TypesenseApi.defineCollection({
name: 'products',
fields: [
{ name: 'id', type: 'string' as const },
{ name: 'title', type: 'string' as const },
{ name: 'description', type: 'string' as const, optional: true },
{ name: 'price', type: 'float' as const },
{ name: 'inStock', type: 'bool' as const },
{ name: 'tags', type: 'string[]' as const, optional: true },
{ name: 'rating', type: 'int32' as const, optional: true }
] as const
} as const)
// Create a strongly-typed API instance
const api = TypesenseApi.createSchemaTypedApi(ProductCollection)({
prefixUrl: 'http://localhost:8108',
token: 'your-api-key'
})
// All operations are now fully typed with autocomplete
await api.documents.insert({
id: 'prod-001',
title: 'Laptop', // ✅ Required, must be string
price: 999.99, // ✅ Required, must be number
inStock: true, // ✅ Required, must be boolean
description: 'Gaming laptop', // ✅ Optional, can be omitted
tags: ['gaming', 'laptop'] // ✅ Optional, must be string[]
})
// TypeScript will catch these errors at compile time:
// ❌ Missing required field
// await api.documents.insert({
// id: 'prod-002',
// price: 99.99,
// inStock: true
// // Error: Property 'title' is missing
// })
// ❌ Wrong type
// await api.documents.insert({
// id: 'prod-003',
// title: 'Product',
// price: '99.99', // Error: Type 'string' is not assignable to type 'number'
// inStock: true
// })One-Step API Creation
For simpler cases, you can define and create the API in one step:
const api = TypesenseApi.createFromSchema({
name: 'products',
fields: [
{ name: 'id', type: 'string' as const },
{ name: 'title', type: 'string' as const },
{ name: 'price', type: 'float' as const },
{ name: 'inStock', type: 'bool' as const }
] as const
} as const)({
prefixUrl: 'http://localhost:8108',
token: 'your-api-key'
})Complex Field Types
The type inference supports all Typesense field types:
const EventCollection = TypesenseApi.defineCollection({
name: 'events',
fields: [
{ name: 'id', type: 'string' as const },
{ name: 'name', type: 'string' as const },
{ name: 'timestamp', type: 'int64' as const },
{ name: 'location', type: 'geopoint' as const }, // [lat, lon] tuple
{ name: 'attendees', type: 'int32[]' as const, optional: true },
{ name: 'metadata', type: 'object' as const, optional: true },
{ name: 'tags', type: 'auto' as const, optional: true } // string | string[]
] as const
} as const)
const api = TypesenseApi.createSchemaTypedApi(EventCollection)({
prefixUrl: 'http://localhost:8108',
token: 'your-api-key'
})
// Properly typed document
await api.documents.insert({
id: 'evt-001',
name: 'Tech Conference',
timestamp: Date.now(),
location: [37.7749, -122.4194], // Geopoint as [lat, lon]
attendees: [100, 200, 300], // Optional int32 array
metadata: { venue: 'Moscone Center' } // Optional object
})Key Features
- Compile-time type checking - No runtime overhead
- Full autocomplete support - Your IDE knows all field names and types
- Optional field handling - Correctly distinguishes between required and optional fields
- All Typesense types supported - Including arrays, objects, geopoints, and auto fields
- Zero runtime validation - Pure TypeScript type inference
Alternative Import Methods
The utility functions are also available as direct imports:
import { defineCollection, createSchemaTypedApi } from '@goatlab/typesense'
const collection = defineCollection({...})
const api = createSchemaTypedApi(collection)({...})Type Mapping Reference
| Typesense Type | TypeScript Type |
|---|---|
string |
string |
string[] |
string[] |
int32, int64 |
number |
int32[], int64[] |
number[] |
float |
number |
float[] |
number[] |
bool |
boolean |
bool[] |
boolean[] |
geopoint |
[number, number] |
geopoint[] |
[number, number][] |
object |
Record<string, any> |
object[] |
Record<string, any>[] |
auto |
string | string[] |
Note: The id field is excluded from the document type for insert() operations, as it's handled separately by the TypesenseApi with WithRequiredId<T> type.
Advanced Configuration
const typesense = new TypesenseApi({
prefixUrl: 'https://typesense.example.com',
token: 'your-api-key',
// Multi-tenancy
tenantId: 'customer-123',
// Timeouts
searchTimeout: 5000,
importTimeout: 60000,
defaultTimeout: 10000,
// Resilience settings
resilience: {
maxFailures: 5,
resetTimeout: 60000,
halfOpenRequests: 3
},
// Other options
autoCreateCollection: true,
enableVersionCheck: true,
suppressLogs: false
})Components
The package includes several utility components that can be used independently:
TypesenseHttpClient- HTTP client with built-in authenticationResiliencePolicy- Circuit breaker and rate limiting implementationCollectionSchemaManager- Schema caching and managementTypesenseFilterBuilder- Fluent filter query builderExportFormatter- Document export formatting utilities