-
Notifications
You must be signed in to change notification settings - Fork 35
JavaScript Guide
rUv edited this page Jul 31, 2025
·
1 revision
Complete guide to using FACT with JavaScript and Node.js, including WASM integration and browser deployment.
- Overview
- Installation
- Node.js Integration
- Browser Integration
- WASM Usage
- TypeScript Support
- API Reference
- Examples
- Performance Tips
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.
- 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
# Install via npm (when available)
npm install fact-wasm
# Or install globally
npm install -g fact-wasm<!-- 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># 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// 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');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);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');
});<!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>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;<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>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`);// 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));// 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;
}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
};
}
}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
}class QueryProcessor {
// Constructor
constructor()
// Methods
process(query: string): string
analyze(data: string): string
processWithTemplate(data: string, template: string): string
}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
}// 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();// 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 });
});
}// 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();
}
}
}// 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;
}// 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.