pulse-ai-utils
Version:
Utility functions and helpers for AI-powered applications
100 lines • 3.27 kB
JavaScript
;
/**
* Helper functions for working with pgvector data in Supabase
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseVectorString = parseVectorString;
exports.formatVectorForInsert = formatVectorForInsert;
exports.getEmbeddingArray = getEmbeddingArray;
exports.cosineSimilarity = cosineSimilarity;
exports.prepareContentForBulkInsert = prepareContentForBulkInsert;
exports.transformSupabaseResponse = transformSupabaseResponse;
/**
* Parse a pgvector string representation to a JavaScript array
* Handles the string format returned by Supabase: "[0.1,0.2,0.3,...]"
*/
function parseVectorString(vectorString) {
if (!vectorString || typeof vectorString !== 'string') {
return [];
}
try {
// Remove brackets and split by comma
const cleanString = vectorString.replace(/^\[|\]$/g, '');
return cleanString.split(',').map(val => parseFloat(val.trim()));
}
catch (error) {
console.error('Error parsing vector string:', error);
return [];
}
}
/**
* Convert a JavaScript array to pgvector format for insertion
* This handles the proper formatting for Supabase/PostgreSQL
*/
function formatVectorForInsert(vector) {
return JSON.stringify(vector);
}
/**
* Safely get embedding from Supabase response
* Handles both array and string formats
*/
function getEmbeddingArray(data) {
if (!data?.embedding)
return null;
// If it's already an array, return it
if (Array.isArray(data.embedding)) {
return data.embedding;
}
// If it's a string, parse it
if (typeof data.embedding === 'string') {
return parseVectorString(data.embedding);
}
// If it's an object (from JSONB cast), extract the array
if (typeof data.embedding === 'object' && data.embedding !== null) {
// Handle JSONB format that might come from our SQL functions
if (Array.isArray(data.embedding)) {
return data.embedding;
}
}
return null;
}
/**
* Calculate cosine similarity between two vectors
* Useful for client-side similarity calculations
*/
function cosineSimilarity(vec1, vec2) {
if (!vec1 || !vec2 || vec1.length !== vec2.length) {
throw new Error('Vectors must have the same length');
}
let dotProduct = 0;
let norm1 = 0;
let norm2 = 0;
for (let i = 0; i < vec1.length; i++) {
dotProduct += vec1[i] * vec2[i];
norm1 += vec1[i] * vec1[i];
norm2 += vec2[i] * vec2[i];
}
const denominator = Math.sqrt(norm1) * Math.sqrt(norm2);
return denominator === 0 ? 0 : dotProduct / denominator;
}
/**
* Batch process content with embeddings
* Ensures proper formatting for bulk operations
*/
function prepareContentForBulkInsert(documents) {
return documents.map(doc => ({
...doc,
embedding: doc.embedding ? formatVectorForInsert(doc.embedding) : null
}));
}
/**
* Transform Supabase response to ensure embeddings are arrays
* Use this after fetching data with embedding fields
*/
function transformSupabaseResponse(data) {
return data.map(item => ({
...item,
embedding: item.embedding ? getEmbeddingArray(item) : null
}));
}
//# sourceMappingURL=vector-helpers.js.map