Skip to content

JavaScript Guide

rUv edited this page Jul 31, 2025 · 1 revision

JavaScript Guide

Complete guide to using FACT with JavaScript and Node.js, including WASM integration and browser deployment.

📚 Table of Contents

Overview

FACT provides JavaScript integration through WebAssembly (WASM) bindings, offering high-performance data processing capabilities in both Node.js and browser environments. The JavaScript interface maintains the same cognitive template system and caching capabilities as the native implementations.

Key Features

  • WASM Performance - Near-native speed with WebAssembly
  • Universal Compatibility - Works in Node.js and browsers
  • TypeScript Support - Full type definitions included
  • Async/Await - Modern JavaScript patterns
  • Streaming Support - Handle large datasets efficiently
  • Memory Management - Automatic garbage collection integration

Installation

NPM Package (Coming Soon)

# Install via npm (when available)
npm install fact-wasm

# Or install globally
npm install -g fact-wasm

CDN (Browser)

<!-- Development version -->
<script src="https://unpkg.com/fact-wasm/dist/fact.dev.js"></script>

<!-- Production version -->
<script src="https://unpkg.com/fact-wasm/dist/fact.min.js"></script>

Build from Source

# Clone repository
git clone https://github.com/ruvnet/FACT.git
cd FACT/cargo-crate

# Build WASM package
wasm-pack build --target web --out-dir ../pkg

# Use in your project
npm link ../pkg

Node.js Integration

Basic Setup

// Import FACT WASM module
const { FastCache, QueryProcessor, FACTManager } = require('fact-wasm');

// Initialize components
const cache = new FastCache(1000);
const processor = new QueryProcessor();
const fact = new FACTManager({
    cacheSize: 5000,
    defaultTTL: 600
});

console.log('FACT initialized successfully');

Processing Data

const processFinancialData = async (data) => {
    try {
        // Process with template
        const result = await fact.process(data, {
            template: 'financial-analysis',
            useCache: true,
            ttl: 3600
        });
        
        console.log('Analysis complete:', result.data);
        console.log('Cache hit:', result.metadata.cacheHit);
        
        return result;
    } catch (error) {
        console.error('Processing failed:', error);
        throw error;
    }
};

// Example usage
const financialData = {
    revenues: [1000000, 1200000, 980000, 1500000],
    quarters: ['Q1', 'Q2', 'Q3', 'Q4'],
    sector: 'technology'
};

processFinancialData(financialData);

Express.js Integration

const express = require('express');
const { FACTManager } = require('fact-wasm');

const app = express();
const fact = new FACTManager();

// Middleware for FACT processing
app.use('/api/analyze', async (req, res, next) => {
    try {
        const result = await fact.analyze(req.body);
        res.json({
            success: true,
            data: result,
            performance: {
                processingTime: result.metadata.processingTime,
                cacheHit: result.metadata.cacheHit
            }
        });
    } catch (error) {
        next(error);
    }
});

// Health check with cache stats
app.get('/api/health', (req, res) => {
    const stats = fact.getCacheStats();
    res.json({
        status: 'healthy',
        cache: {
            hitRate: stats.hitRate,
            size: stats.size,
            evictions: stats.evictions
        }
    });
});

app.listen(3000, () => {
    console.log('FACT API server running on port 3000');
});

Browser Integration

Basic HTML Setup

<!DOCTYPE html>
<html>
<head>
    <title>FACT Browser Demo</title>
    <script type="module">
        import init, { FastCache, QueryProcessor } from './fact_wasm.js';
        
        async function initFACT() {
            // Initialize WASM
            await init();
            
            // Create instances
            const cache = new FastCache(1000);
            const processor = new QueryProcessor();
            
            // Setup UI event handlers
            document.getElementById('analyze').addEventListener('click', async () => {
                const input = document.getElementById('data').value;
                const result = processor.analyze(input);
                document.getElementById('result').textContent = result;
            });
            
            console.log('FACT ready for browser use');
        }
        
        initFACT();
    </script>
</head>
<body>
    <h1>FACT Browser Demo</h1>
    <textarea id="data" placeholder="Enter JSON data"></textarea>
    <button id="analyze">Analyze</button>
    <pre id="result"></pre>
</body>
</html>

React Integration

import React, { useState, useEffect, useRef } from 'react';
import init, { FACTManager } from 'fact-wasm';

const FACTProcessor = () => {
    const [initialized, setInitialized] = useState(false);
    const [result, setResult] = useState(null);
    const [loading, setLoading] = useState(false);
    const factRef = useRef(null);
    
    // Initialize FACT
    useEffect(() => {
        const initFACT = async () => {
            await init();
            factRef.current = new FACTManager({
                cacheSize: 2000,
                enableLogging: process.env.NODE_ENV === 'development'
            });
            setInitialized(true);
        };
        
        initFACT();
    }, []);
    
    const processData = async (data) => {
        if (!initialized || !factRef.current) return;
        
        setLoading(true);
        try {
            const processed = await factRef.current.process(data, {
                template: 'analysis-basic',
                useCache: true
            });
            setResult(processed);
        } catch (error) {
            console.error('Processing failed:', error);
        } finally {
            setLoading(false);
        }
    };
    
    return (
        <div className="fact-processor">
            <h2>FACT Data Processor</h2>
            {!initialized ? (
                <div>Initializing FACT...</div>
            ) : (
                <div>
                    <button 
                        onClick={() => processData({ values: [1,2,3,4,5] })}
                        disabled={loading}
                    >
                        {loading ? 'Processing...' : 'Process Sample Data'}
                    </button>
                    {result && (
                        <div className="result">
                            <h3>Results:</h3>
                            <pre>{JSON.stringify(result, null, 2)}</pre>
                        </div>
                    )}
                </div>
            )}
        </div>
    );
};

export default FACTProcessor;

Vue.js Integration

<template>
  <div class="fact-app">
    <h1>FACT Vue Demo</h1>
    <div v-if="!initialized">Loading FACT...</div>
    <div v-else>
      <input v-model="inputData" placeholder="Enter data" />
      <button @click="processData" :disabled="processing">
        {{ processing ? 'Processing...' : 'Analyze' }}
      </button>
      <div v-if="result" class="result">
        <h3>Analysis Result:</h3>
        <pre>{{ JSON.stringify(result, null, 2) }}</pre>
      </div>
    </div>
  </div>
</template>

<script>
import init, { FACTManager } from 'fact-wasm'

export default {
  name: 'FACTApp',
  data() {
    return {
      initialized: false,
      processing: false,
      inputData: '',
      result: null,
      fact: null
    }
  },
  async mounted() {
    await init()
    this.fact = new FACTManager()
    this.initialized = true
  },
  methods: {
    async processData() {
      if (!this.inputData) return
      
      this.processing = true
      try {
        const data = JSON.parse(this.inputData)
        this.result = await this.fact.analyze(data)
      } catch (error) {
        console.error('Processing error:', error)
      } finally {
        this.processing = false
      }
    }
  }
}
</script>

WASM Usage

Direct WASM API

import init, { 
    FastCache, 
    QueryProcessor, 
    wasm_memory 
} from './fact_wasm.js';

// Initialize WASM module
await init();

// Create cache with 1000 entries
const cache = new FastCache(1000);

// Cache operations
cache.set('user:123', JSON.stringify({ name: 'John' }), 300);
const userData = cache.get('user:123');
console.log('Cached user:', JSON.parse(userData));

// Check cache statistics
const stats = cache.stats();
console.log(`Cache hit rate: ${stats.hitRate * 100}%`);

// Memory usage
console.log(`WASM memory usage: ${wasm_memory.buffer.byteLength} bytes`);

Advanced WASM Operations

// Custom template processing
const processor = new QueryProcessor();

// Register custom template
const customTemplate = {
    name: 'revenue-analysis',
    operations: [
        { type: 'transform', field: 'revenue', normalize: true },
        { type: 'analyze', metrics: ['growth', 'trend'] },
        { type: 'aggregate', groupBy: 'quarter' }
    ]
};

// Process with custom template
const data = {
    revenues: [1000, 1200, 980, 1500],
    quarters: ['Q1', 'Q2', 'Q3', 'Q4']
};

const result = processor.processWithTemplate(
    JSON.stringify(data),
    'revenue-analysis'
);

console.log('Analysis:', JSON.parse(result));

TypeScript Support

Type Definitions

// fact-wasm.d.ts
export interface CacheStats {
    hits: number;
    misses: number;
    hitRate: number;
    size: number;
    evictions: number;
}

export interface ProcessOptions {
    template?: string;
    useCache?: boolean;
    ttl?: number;
}

export interface ProcessResult<T = any> {
    data: T;
    metadata: {
        processingTime: number;
        cacheHit: boolean;
        template: string;
    };
}

export class FastCache {
    constructor(maxSize: number);
    get(key: string): string | null;
    set(key: string, value: string, ttl?: number): void;
    delete(key: string): boolean;
    clear(): void;
    stats(): CacheStats;
    size(): number;
}

export class FACTManager {
    constructor(config?: FACTConfig);
    process<T>(data: any, options?: ProcessOptions): Promise<ProcessResult<T>>;
    analyze(data: any): Promise<AnalysisResult>;
    getCacheStats(): CacheStats;
    clearCache(): void;
}

TypeScript Usage

import { FACTManager, ProcessResult } from 'fact-wasm';

interface FinancialData {
    revenues: number[];
    quarters: string[];
    sector: string;
}

interface AnalysisResult {
    totalRevenue: number;
    growthRate: number;
    trends: string[];
}

class FinancialAnalyzer {
    private fact: FACTManager;
    
    constructor() {
        this.fact = new FACTManager({
            cacheSize: 5000,
            defaultTTL: 3600
        });
    }
    
    async analyzeFinancials(data: FinancialData): Promise<AnalysisResult> {
        const result: ProcessResult<AnalysisResult> = await this.fact.process(
            data,
            { template: 'financial-analysis', useCache: true }
        );
        
        return result.data;
    }
    
    getCachePerformance(): { hitRate: number; size: number } {
        const stats = this.fact.getCacheStats();
        return {
            hitRate: stats.hitRate,
            size: stats.size
        };
    }
}

API Reference

FastCache Class

class FastCache {
    // Constructor
    constructor(maxSize: number)
    
    // Methods
    get(key: string): string | null
    set(key: string, value: string, ttl?: number): void
    delete(key: string): boolean
    clear(): void
    stats(): CacheStats
    size(): number
}

QueryProcessor Class

class QueryProcessor {
    // Constructor
    constructor()
    
    // Methods
    process(query: string): string
    analyze(data: string): string
    processWithTemplate(data: string, template: string): string
}

FACTManager Class

class FACTManager {
    // Constructor
    constructor(config?: FACTConfig)
    
    // Methods
    async process(data: any, options?: ProcessOptions): Promise<ProcessResult>
    async analyze(data: any): Promise<AnalysisResult>
    getCacheStats(): CacheStats
    clearCache(): void
}

Examples

Real-time Dashboard

// Real-time data processing dashboard
class RealTimeDashboard {
    constructor() {
        this.fact = new FACTManager({ cacheSize: 10000 });
        this.websocket = new WebSocket('ws://localhost:8080');
        this.setupWebSocket();
    }
    
    setupWebSocket() {
        this.websocket.onmessage = async (event) => {
            const data = JSON.parse(event.data);
            
            // Process incoming data
            const analysis = await this.fact.analyze(data);
            
            // Update dashboard
            this.updateDashboard(analysis);
        };
    }
    
    updateDashboard(analysis) {
        // Update UI elements
        document.getElementById('metrics').textContent = 
            JSON.stringify(analysis.summary, null, 2);
    }
}

// Initialize dashboard
const dashboard = new RealTimeDashboard();

Batch Processing Worker

// Web Worker for batch processing
// worker.js
import init, { FACTManager } from 'fact-wasm';

let fact;

// Initialize FACT in worker
init().then(() => {
    fact = new FACTManager();
    postMessage({ type: 'ready' });
});

// Handle messages from main thread
onmessage = async (event) => {
    const { type, data, id } = event.data;
    
    if (type === 'process') {
        try {
            const result = await fact.process(data);
            postMessage({ 
                type: 'result', 
                id, 
                result: result.data,
                metadata: result.metadata
            });
        } catch (error) {
            postMessage({ 
                type: 'error', 
                id, 
                error: error.message 
            });
        }
    }
};

// Main thread usage
const worker = new Worker('worker.js');
const pendingTasks = new Map();

worker.onmessage = (event) => {
    const { type, id, result, error } = event.data;
    
    if (type === 'result') {
        const resolve = pendingTasks.get(id);
        if (resolve) {
            resolve(result);
            pendingTasks.delete(id);
        }
    }
};

// Process data using worker
function processData(data) {
    return new Promise((resolve) => {
        const id = Math.random().toString(36);
        pendingTasks.set(id, resolve);
        worker.postMessage({ type: 'process', data, id });
    });
}

Performance Tips

Memory Management

// Efficient memory usage
class MemoryOptimizedProcessor {
    constructor() {
        this.fact = new FACTManager({
            cacheSize: 1000, // Don't over-allocate
            defaultTTL: 300   // Shorter TTL for dynamic data
        });
        
        // Clean up periodically
        setInterval(() => {
            this.cleanup();
        }, 60000);
    }
    
    cleanup() {
        const stats = this.fact.getCacheStats();
        
        // Clear cache if hit rate is low
        if (stats.hitRate < 0.5) {
            this.fact.clearCache();
        }
    }
}

Batch Operations

// Process multiple items efficiently
async function batchProcess(items) {
    const batchSize = 10;
    const results = [];
    
    for (let i = 0; i < items.length; i += batchSize) {
        const batch = items.slice(i, i + batchSize);
        const batchResults = await Promise.all(
            batch.map(item => fact.process(item))
        );
        results.push(...batchResults);
    }
    
    return results;
}

Streaming Data

// Handle streaming data efficiently
class StreamProcessor {
    constructor() {
        this.fact = new FACTManager();
        this.buffer = [];
        this.bufferSize = 100;
    }
    
    async processStream(dataChunk) {
        this.buffer.push(dataChunk);
        
        if (this.buffer.length >= this.bufferSize) {
            await this.flushBuffer();
        }
    }
    
    async flushBuffer() {
        if (this.buffer.length === 0) return;
        
        const batch = this.buffer.splice(0);
        const results = await this.fact.process({
            type: 'batch',
            items: batch
        });
        
        return results;
    }
}

For more JavaScript examples and patterns, see the Examples page and WASM Integration guide.

Clone this wiki locally