#!/usr/bin/env node /** * Write-Only Mode with Direct Reads Demo * * This example demonstrates the new allowDirectReads feature that enables * direct storage operations in write-only mode for efficient deduplication * without loading expensive search indexes. */ import { BrainyData } from '../dist/index.js' // Simulate external API calls const mockBlueskyAPI = { async getProfile(did) { // Simulate network latency await new Promise(resolve => setTimeout(resolve, 100)) return { did, handle: `user-${did.split(':')[2]}`, displayName: `User ${did.split(':')[2]}`, followersCount: Math.floor(Math.random() * 1000), postsCount: Math.floor(Math.random() * 500), createdAt: new Date().toISOString() } } } async function demonstrateWriteOnlyDirectReads() { console.log('๐Ÿš€ Write-Only Mode with Direct Reads Demo\n') // Create instances with different configurations console.log('๐Ÿ“ Creating BrainyData instances...') const writerOnlyService = new BrainyData({ writeOnly: true, allowDirectReads: false }) const writerWithReadsService = new BrainyData({ writeOnly: true, allowDirectReads: true }) const fullService = new BrainyData({ writeOnly: false }) await writerOnlyService.init() await writerWithReadsService.init() await fullService.init() console.log('โœ… All instances initialized\n') // Demonstrate the problem with write-only mode without direct reads console.log('โŒ Problem: Write-only mode without direct reads') console.log(' - Cannot check for existing data') console.log(' - Must make redundant API calls') console.log(' - No efficient deduplication possible\n') // Simulate Bluesky service with write-only + direct reads console.log('โœ… Solution: Write-only mode WITH direct reads') const processMessage = async (did, messageData) => { console.log(` Processing message from ${did}...`) // Check if profile already exists (direct storage lookup) const existingProfile = await writerWithReadsService.get(did) if (!existingProfile) { console.log(` ๐Ÿ“ก Making API call for new DID: ${did}`) // Simulate API call const profileData = await mockBlueskyAPI.getProfile(did) // Store the profile const profileVector = new Array(384).fill(Math.random() * 0.1) await writerWithReadsService.add(profileVector, profileData, { id: did }) return { action: 'created', profile: profileData, apiCall: true } } else { console.log(` โšก Using cached profile for: ${did}`) // Profile exists, skip API call return { action: 'existing', profile: existingProfile.metadata, apiCall: false } } } // Test deduplication efficiency console.log('\n๐Ÿ”„ Testing deduplication efficiency...') const testDIDs = [ 'did:plc:user123', 'did:plc:user456', 'did:plc:user123', // Duplicate 'did:plc:user789', 'did:plc:user123', // Another duplicate 'did:plc:user456' // Another duplicate ] let apiCallCount = 0 const results = [] console.log(`\n๐Ÿ“Š Processing ${testDIDs.length} messages...`) for (const did of testDIDs) { const result = await processMessage(did, { text: `Message from ${did}` }) results.push(result) if (result.apiCall) apiCallCount++ } console.log(`\n๐Ÿ“ˆ Results:`) console.log(` โ€ข Total messages processed: ${testDIDs.length}`) console.log(` โ€ข Unique profiles: ${new Set(testDIDs).size}`) console.log(` โ€ข API calls made: ${apiCallCount}`) console.log(` โ€ข API calls saved: ${testDIDs.length - apiCallCount}`) console.log(` โ€ข Efficiency: ${Math.round((1 - apiCallCount / testDIDs.length) * 100)}% reduction in API calls`) // Demonstrate direct read operations console.log('\n๐Ÿ” Testing direct read operations...') const testDID = 'did:plc:user123' console.log(` โ€ข get('${testDID}'): ${await writerWithReadsService.get(testDID) ? 'โœ… Found' : 'โŒ Not found'}`) console.log(` โ€ข has('${testDID}'): ${await writerWithReadsService.has(testDID) ? 'โœ… Exists' : 'โŒ Missing'}`) console.log(` โ€ข exists('${testDID}'): ${await writerWithReadsService.exists(testDID) ? 'โœ… Exists' : 'โŒ Missing'}`) const metadata = await writerWithReadsService.getMetadata(testDID) console.log(` โ€ข getMetadata('${testDID}'): ${metadata ? `โœ… ${metadata.handle}` : 'โŒ No metadata'}`) const batchResults = await writerWithReadsService.getBatch([ 'did:plc:user123', 'did:plc:user456', 'did:plc:nonexistent' ]) console.log(` โ€ข getBatch([3 items]): ${batchResults.filter(r => r !== null).length}/3 found`) // Demonstrate that search operations are still blocked console.log('\n๐Ÿšซ Confirming search operations are blocked...') try { await writerWithReadsService.search('test') console.log(' โŒ ERROR: Search should have failed!') } catch (error) { console.log(' โœ… search() correctly blocked:', error.message.split('.')[0]) } // Performance comparison console.log('\nโšก Performance Benefits:') console.log(' โ€ข No search index loading in memory') console.log(' โ€ข Fast direct storage lookups') console.log(' โ€ข Reduced memory footprint') console.log(' โ€ข Optimal for high-throughput data ingestion') console.log(' โ€ข Perfect for microservices with specific roles') // Configuration examples console.log('\nโš™๏ธ Configuration Examples:') console.log(` // Writer service with deduplication const writerService = new BrainyData({ writeOnly: true, // No search index allowDirectReads: true // Enable direct ID lookups }) // Pure writer service (no reads) const pureWriter = new BrainyData({ writeOnly: true, // No search index allowDirectReads: false // No read operations }) // Full-featured service const readerService = new BrainyData({ writeOnly: false // Full search capabilities }) `) // Cleanup console.log('๐Ÿงน Cleaning up...') await writerOnlyService.cleanup?.() await writerWithReadsService.cleanup?.() await fullService.cleanup?.() console.log('โœจ Demo completed successfully!') } // Run the demo demonstrateWriteOnlyDirectReads().catch(console.error)