Node.js SDK
The official Torque Node.js SDK provides an HTTP client and TCP binary ingest client. Zero external dependencies — uses native fetch and Node.js built-in modules. Requires Node.js 20+.
Installation
npm install @truespar/torque-http
HTTP Client
The TorqueHttpClient class provides full access to the Torque REST API:
import { TorqueHttpClient } from '@truespar/torque-http';
const client = new TorqueHttpClient({
url: 'http://localhost:8108',
apiKey: 'YOUR_API_KEY',
});
// Health check
const health = await client.health();
// Search
const results = await client.search('products', {
q: 'running shoes',
query_by: 'title,description',
filter_by: 'in_stock:true',
sort_by: 'price:asc',
per_page: 20,
});
for (const hit of results.hits) {
console.log(`${hit.document.title} - ${hit.document.price}`);
}
Multi-Node with Failover
const client = new TorqueHttpClient({
nodes: [
{ host: 'node1.example.com', port: 8108, protocol: 'https' },
{ host: 'node2.example.com', port: 8108, protocol: 'https' },
],
apiKey: 'YOUR_API_KEY',
retries: 3,
});
Collection Management
// Create a collection
await client.createCollection({
name: 'products',
fields: [
{ name: 'title', type: 'string' },
{ name: 'price', type: 'float', sort: true },
{ name: 'category', type: 'string', facet: true },
],
default_sorting_field: 'price',
});
// List collections
const collections = await client.listCollections();
// Delete a collection
await client.deleteCollection('products');
Document Operations
// Import documents (JSONL)
const results = await client.importDocuments('products', [
{ id: '1', title: 'Running Shoes', price: 89.99, category: 'Footwear' },
{ id: '2', title: 'Laptop Stand', price: 49.99, category: 'Electronics' },
], { action: 'upsert' });
// Export documents
const docs = await client.exportDocuments('products');
// CRUD
await client.createDocument('products', { id: '3', title: 'Mouse', price: 29.99 });
const doc = await client.getDocument('products', '3');
await client.updateDocument('products', '3', { price: 24.99 });
await client.deleteDocument('products', '3');
Grouped & Multi-Search
// Grouped search (use group_by parameter with search)
const grouped = await client.search('products', {
q: 'shoes',
query_by: 'title',
group_by: 'brand',
group_limit: 3,
});
for (const group of grouped.grouped_hits) {
console.log(`Brand: ${group.group_key.join(', ')} (${group.found} hits)`);
}
// Multi-search
const multi = await client.multiSearch([
{ collection: 'products', q: 'shoes', query_by: 'title' },
{ collection: 'articles', q: 'shoes', query_by: 'body' },
]);
Aliases, Keys & More
// Aliases (alias name first, then target collection)
await client.upsertAlias('products_alias', 'products');
const aliases = await client.listAliases();
// API keys
const key = await client.createKey({
description: 'Search only',
actions: ['documents:search'],
collections: ['products'],
});
// Synonyms, presets, stopwords
await client.upsertSynonymSet('my_synonyms', { synonyms: [{root: 'laptop', synonyms: ['notebook']}] });
await client.upsertPreset('my_preset', { value: {q: 'default', query_by: 'title'} });
await client.upsertStopwords('my_stopwords', { stopwords: ['the', 'a', 'an'] });
TCP Binary Ingestion
The TorqueIngestClient provides high-throughput document streaming via the binary TCP protocol:
import { TorqueIngestClient, DocumentEncoder } from '@truespar/torque-http';
const schema = [
{ name: 'title', type: 'string' },
{ name: 'price', type: 'float' },
{ name: 'category', type: 'string' },
];
const ingest = new TorqueIngestClient();
await ingest.connect('localhost', 8109);
await ingest.startIngest('products');
// Send document dicts in batches — DocumentEncoder encodes internally
let batch = [];
for (let i = 0; i < 100000; i++) {
batch.push({
id: `product_${i}`,
title: `Product ${i}`,
price: 9.99 + i * 0.01,
category: 'Electronics',
});
if (batch.length === 5000) {
await ingest.sendBatch(batch, schema);
batch = [];
}
}
if (batch.length) await ingest.sendBatch(batch, schema);
const result = await ingest.commit();
console.log(`Committed: seq=${result.batchSeq}, docs=${result.docsReceived}`);
ingest.close();
TQBF Binary File Writer
import { TorqueBinaryWriter } from '@truespar/torque-http';
const writer = new TorqueBinaryWriter(schema, 'output.tqbf');
for (let i = 0; i < 100000; i++) {
writer.write({ id: `p_${i}`, title: `Product ${i}`, price: 9.99 });
}
writer.finalize();
// Upload: POST /collections/products/documents/import-binary --data-binary @output.tqbf
HMAC Scoped Keys
const scopedKey = client.generateScopedSearchKey(
'your-search-key',
{ filter_by: 'company_id:=123' },
);
TypeScript Support
The SDK includes TypeScript type definitions in types/index.d.ts. All method signatures, search parameters, and response types are fully typed.
Error Handling
HTTP API errors throw typed error classes:
| Error Class | HTTP Status |
|---|---|
RequestMalformed | 400 |
RequestUnauthorized | 401 |
RequestForbidden | 403 |
ObjectNotFound | 404 |
ObjectAlreadyExists | 409 |
ServerError | 500 |
ServiceUnavailable | 503 |
All errors extend TorqueApiError which provides statusCode and message properties.