UNPKG

@goatlab/typesense

Version:

Modern TypeScript wrapper for Typesense search engine API

208 lines 7.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExportFormatter = void 0; class ExportFormatter { static formatDocuments(documents, format) { switch (format) { case 'json': return documents; case 'jsonl': return documents.map(doc => JSON.stringify(doc)).join('\n'); case 'csv': return ExportFormatter.formatCSV(documents); default: throw new Error(`Unsupported export format: ${format}`); } } static formatCSV(documents) { if (documents.length === 0) { return ''; } // Get all unique keys from all documents const allKeys = new Set(); documents.forEach(doc => { Object.keys(doc).forEach(key => allKeys.add(key)); }); const headers = Array.from(allKeys).sort(); const csvLines = [headers.join(',')]; for (const doc of documents) { const row = headers.map(header => { const value = doc[header]; return ExportFormatter.escapeCsvValue(value); }); csvLines.push(row.join(',')); } return csvLines.join('\n'); } static createStreamingCSVTransform() { let isFirstRow = true; let headers = []; return new TransformStream({ transform(chunk, controller) { try { if (isFirstRow) { // Extract headers from first document headers = Object.keys(chunk).sort(); controller.enqueue(`${headers.join(',')}\n`); isFirstRow = false; } // Convert document to CSV row const row = headers.map(header => { const value = chunk[header]; return ExportFormatter.escapeCsvValue(value); }); controller.enqueue(`${row.join(',')}\n`); } catch (error) { controller.error(error); } }, }); } static createStreamingJSONLTransform() { return new TransformStream({ transform(chunk, controller) { controller.enqueue(`${JSON.stringify(chunk)}\n`); }, }); } static createGzipStream() { throw new Error('createGzipStream is not available in browser environments. Use CompressionStream API or a server-side solution.'); } static createDocumentParser(format) { switch (format) { case 'jsonl': return ExportFormatter.createJSONLParser(); case 'json': return ExportFormatter.createJSONParser(); default: throw new Error(`Parsing not supported for format: ${format}`); } } static createJSONLParser() { let buffer = ''; return new TransformStream({ transform(chunk, controller) { buffer += chunk; const lines = buffer.split('\n'); // Keep the last incomplete line in buffer buffer = lines.pop() || ''; for (const line of lines) { if (line.trim()) { try { controller.enqueue(JSON.parse(line)); } catch (_error) { controller.error(new Error(`Invalid JSON in line: ${line}`)); return; } } } }, flush(controller) { if (buffer.trim()) { try { controller.enqueue(JSON.parse(buffer)); } catch (_error) { controller.error(new Error(`Invalid JSON in final line: ${buffer}`)); } } }, }); } static createJSONParser() { let buffer = ''; return new TransformStream({ transform(chunk, _controller) { buffer += chunk; }, flush(controller) { try { const documents = JSON.parse(buffer); if (Array.isArray(documents)) { documents.forEach(doc => controller.enqueue(doc)); } else { controller.enqueue(documents); } } catch (error) { controller.error(new Error(`Invalid JSON: ${error.message}`)); } }, }); } static escapeCsvValue(value) { if (value === null || value === undefined) { return ''; } let stringValue = String(value); // Handle arrays by joining with semicolons if (Array.isArray(value)) { stringValue = value.map(item => String(item)).join(';'); } // Handle objects by stringifying if (typeof value === 'object' && !Array.isArray(value)) { stringValue = JSON.stringify(value); } // Escape quotes and wrap in quotes if needed const needsQuoting = stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n') || stringValue.includes('\r'); if (needsQuoting) { // Escape existing quotes by doubling them stringValue = stringValue.replace(/"/g, '""'); return `"${stringValue}"`; } return stringValue; } static async streamToString(stream) { const reader = stream.getReader(); const decoder = new TextDecoder(); let result = ''; while (true) { const { done, value } = await reader.read(); if (done) { break; } result += typeof value === 'string' ? value : decoder.decode(value, { stream: true }); } result += decoder.decode(); return result; } static async *streamToAsyncIterator(stream) { const reader = stream.getReader(); try { while (true) { const { done, value } = await reader.read(); if (done) { break; } yield value; } } finally { reader.releaseLock(); } } static createDocumentStream(documents) { let index = 0; return new ReadableStream({ pull(controller) { if (index < documents.length) { controller.enqueue(documents[index++]); } else { controller.close(); } }, }); } } exports.ExportFormatter = ExportFormatter; //# sourceMappingURL=export-formatter.js.map