claude-flow-novice
Version:
Claude Flow Novice - Advanced orchestration platform for multi-agent AI workflows with CFN Loop architecture Includes Local RuVector Accelerator and all CFN skills for complete functionality.
103 lines (102 loc) • 3.7 kB
JavaScript
import Redis from 'ioredis';
import { performance } from 'perf_hooks';
import { v4 as uuidv4 } from 'uuid';
import { generateTraceId } from './types/event-bus.types.js';
// TODO: Import WASM JSON parser when available
// import { parseJsonWithWasm } from '../wasm/json-parser.js';
export class QEEventBus {
redis;
topics = new Set();
subscriptions = new Map();
config;
constructor(config = {}){
this.config = {
redisUrl: process.env.CFN_REDIS_URL || process.env.REDIS_URL || `redis://${process.env.CFN_REDIS_HOST || 'cfn-redis'}:${process.env.CFN_REDIS_PORT || 6379}`,
performanceThreshold: 100,
...config
};
this.redis = new Redis(this.config.redisUrl);
// Set up Redis pub/sub listener
this.initRedisSubscription();
}
initRedisSubscription() {
const redisSub = new Redis(this.config.redisUrl);
redisSub.on('message', async (topic, message)=>{
const startTime = performance.now();
try {
const { payload, metadata } = JSON.parse(message);
const matchingSubscriptions = Array.from(this.subscriptions.values()).filter((sub)=>sub.topic === topic);
await Promise.all(matchingSubscriptions.map((sub)=>sub.callback(payload, metadata)));
} catch (error) {
console.error(`Event processing error for topic ${topic}:`, error);
}
const processingTime = performance.now() - startTime;
if (processingTime > (this.config.performanceThreshold || 100)) {
console.warn(`Event processing for ${topic} took ${processingTime}ms`);
}
});
// Subscribe to all currently registered topics
this.topics.forEach((topic)=>redisSub.subscribe(topic));
}
// Event Router Implementation
registerTopic(topic) {
if (!this.topics.has(topic)) {
this.topics.add(topic);
this.redis.subscribe(topic);
}
}
removeTopic(topic) {
if (this.topics.has(topic)) {
this.topics.delete(topic);
this.redis.unsubscribe(topic);
}
}
listTopics() {
return Array.from(this.topics);
}
// Event Dispatcher Implementation
async publish(topic, payload, traceId) {
if (!this.topics.has(topic)) {
this.registerTopic(topic);
}
const metadata = {
timestamp: Date.now(),
traceId: traceId || generateTraceId()
};
// TODO: Integrate WASM JSON parsing when available
// const parsedPayload = this.config.wasmParserPath
// ? parseJsonWithWasm(payload)
// : payload;
const message = JSON.stringify({
payload,
metadata
});
await this.redis.publish(topic, message);
}
subscribe(topic, callback) {
const subscriptionId = uuidv4();
const subscription = {
id: subscriptionId,
topic,
callback
};
this.subscriptions.set(subscriptionId, subscription);
// Ensure topic is registered
this.registerTopic(topic);
return subscriptionId;
}
unsubscribe(subscriptionId) {
this.subscriptions.delete(subscriptionId);
}
// Agent Lifecycle Event Tracking
trackLifecycleEvent(event, traceId) {
return this.publish('agent-lifecycle', event, traceId);
}
// Graceful Shutdown
async shutdown() {
await this.redis.quit();
}
}
// Singleton export for global access
export const eventBus = new QEEventBus();
//# sourceMappingURL=event-bus.js.map