CRITICAL CHECKPOINT - DO NOT PUSH TO GITHUB Recovery Status: - Successfully recovered brainy.ts from compiled JavaScript - All core v3.0 API methods functional (add, get, update, delete, relate, find, etc.) - Neural subsystem intact (562KB embedded patterns, NLP working) - Augmentation pipeline operational (20+ augmentations) - HNSW clustering system complete - Triple Intelligence compiled (needs constructor fix) - Test suite validates functionality Changes preserved: - 898 files with changes from last 3 days - 144,475 insertions - All augmentation improvements - All test coverage enhancements - Complete v3.0 feature set This is a LOCAL checkpoint only - contains recovered work after corruption incident. Created backup in .backups/brainy-full-20250910-151314.tar.gz Branch: recovery-checkpoint-20250910-151433 Date: Wed Sep 10 03:18:04 PM PDT 2025
233 lines
No EOL
8.3 KiB
JavaScript
233 lines
No EOL
8.3 KiB
JavaScript
/**
|
|
* Conduit Augmentations - Data Synchronization Bridges
|
|
*
|
|
* These augmentations connect and synchronize data between multiple Brainy instances.
|
|
* Now using the unified BrainyAugmentation interface.
|
|
*/
|
|
import { BaseAugmentation } from './brainyAugmentation.js';
|
|
import { v4 as uuidv4 } from '../universal/uuid.js';
|
|
/**
|
|
* Base class for conduit augmentations that sync between Brainy instances
|
|
* Converted to use the unified BrainyAugmentation interface
|
|
*/
|
|
class BaseConduitAugmentation extends BaseAugmentation {
|
|
constructor() {
|
|
super(...arguments);
|
|
this.timing = 'after'; // Conduits run after operations to sync
|
|
this.metadata = 'readonly'; // Conduits read metadata to pass to external systems
|
|
this.operations = ['addNoun', 'delete', 'addVerb'];
|
|
this.priority = 20; // Medium-low priority
|
|
this.connections = new Map();
|
|
}
|
|
async onShutdown() {
|
|
// Close all connections
|
|
for (const [connectionId, connection] of this.connections.entries()) {
|
|
try {
|
|
if (connection.close) {
|
|
await connection.close();
|
|
}
|
|
}
|
|
catch (error) {
|
|
this.log(`Failed to close connection ${connectionId}: ${error}`, 'error');
|
|
}
|
|
}
|
|
this.connections.clear();
|
|
}
|
|
}
|
|
/**
|
|
* WebSocket Conduit Augmentation
|
|
* Syncs data between Brainy instances using WebSockets
|
|
*/
|
|
export class WebSocketConduitAugmentation extends BaseConduitAugmentation {
|
|
constructor() {
|
|
super(...arguments);
|
|
this.name = 'websocket-conduit';
|
|
this.webSocketConnections = new Map();
|
|
this.messageCallbacks = new Map();
|
|
}
|
|
async execute(operation, params, next) {
|
|
// Execute the operation first
|
|
const result = await next();
|
|
// Then sync to connected instances
|
|
if (this.shouldSync(operation)) {
|
|
await this.syncOperation(operation, params, result);
|
|
}
|
|
return result;
|
|
}
|
|
shouldSync(operation) {
|
|
return ['addNoun', 'deleteNoun', 'addVerb'].includes(operation);
|
|
}
|
|
async syncOperation(operation, params, result) {
|
|
// Broadcast to all connected WebSocket instances
|
|
for (const [id, connection] of this.webSocketConnections) {
|
|
if (connection.socket && connection.readyState === 1) { // OPEN state
|
|
try {
|
|
const message = JSON.stringify({
|
|
type: 'sync',
|
|
operation,
|
|
params,
|
|
timestamp: Date.now()
|
|
});
|
|
if (typeof connection.socket.send === 'function') {
|
|
connection.socket.send(message);
|
|
}
|
|
}
|
|
catch (error) {
|
|
this.log(`Failed to sync to ${id}: ${error}`, 'error');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
async establishConnection(url, config) {
|
|
try {
|
|
const connectionId = uuidv4();
|
|
const protocols = config?.protocols;
|
|
// Create WebSocket based on environment
|
|
let socket;
|
|
if (typeof WebSocket !== 'undefined') {
|
|
// Browser environment
|
|
socket = new WebSocket(url, protocols);
|
|
}
|
|
else {
|
|
// Node.js environment - dynamic import
|
|
try {
|
|
const ws = await import('ws');
|
|
socket = new ws.WebSocket(url, protocols);
|
|
}
|
|
catch {
|
|
this.log('WebSocket not available in this environment', 'error');
|
|
return null;
|
|
}
|
|
}
|
|
// Setup event handlers
|
|
socket.onopen = () => {
|
|
this.log(`Connected to ${url}`);
|
|
};
|
|
socket.onmessage = (event) => {
|
|
this.handleMessage(connectionId, event.data);
|
|
};
|
|
socket.onerror = (error) => {
|
|
this.log(`WebSocket error: ${error}`, 'error');
|
|
};
|
|
socket.onclose = () => {
|
|
this.log(`Disconnected from ${url}`);
|
|
this.webSocketConnections.delete(connectionId);
|
|
};
|
|
// Wait for connection to open
|
|
await new Promise((resolve, reject) => {
|
|
const timeout = setTimeout(() => {
|
|
reject(new Error('Connection timeout'));
|
|
}, 5000);
|
|
socket.onopen = () => {
|
|
clearTimeout(timeout);
|
|
resolve();
|
|
};
|
|
socket.onerror = (error) => {
|
|
clearTimeout(timeout);
|
|
reject(error);
|
|
};
|
|
});
|
|
const connection = {
|
|
connectionId,
|
|
url,
|
|
readyState: socket.readyState,
|
|
socket
|
|
};
|
|
this.webSocketConnections.set(connectionId, connection);
|
|
this.connections.set(connectionId, connection);
|
|
return connection;
|
|
}
|
|
catch (error) {
|
|
this.log(`Failed to establish connection to ${url}: ${error}`, 'error');
|
|
return null;
|
|
}
|
|
}
|
|
handleMessage(connectionId, data) {
|
|
try {
|
|
const message = typeof data === 'string' ? JSON.parse(data) : data;
|
|
// Handle sync messages from remote instances
|
|
if (message.type === 'sync') {
|
|
// Apply the operation to our local instance
|
|
this.applySyncOperation(message).catch(error => {
|
|
this.log(`Failed to apply sync operation: ${error}`, 'error');
|
|
});
|
|
}
|
|
// Notify any registered callbacks
|
|
const callbacks = this.messageCallbacks.get(connectionId);
|
|
if (callbacks) {
|
|
callbacks.forEach(callback => callback(message));
|
|
}
|
|
}
|
|
catch (error) {
|
|
this.log(`Failed to handle message: ${error}`, 'error');
|
|
}
|
|
}
|
|
async applySyncOperation(message) {
|
|
// Apply the synced operation to our local Brainy instance
|
|
const { operation, params } = message;
|
|
try {
|
|
switch (operation) {
|
|
case 'addNoun':
|
|
await this.context?.brain.addNoun(params.content, params.metadata);
|
|
break;
|
|
case 'deleteNoun':
|
|
await this.context?.brain.deleteNoun(params.id);
|
|
break;
|
|
case 'addVerb':
|
|
await this.context?.brain.addVerb(params.source, params.target, params.verb, params.metadata);
|
|
break;
|
|
}
|
|
}
|
|
catch (error) {
|
|
this.log(`Failed to apply ${operation}: ${error}`, 'error');
|
|
}
|
|
}
|
|
/**
|
|
* Subscribe to messages from a specific connection
|
|
*/
|
|
onMessage(connectionId, callback) {
|
|
if (!this.messageCallbacks.has(connectionId)) {
|
|
this.messageCallbacks.set(connectionId, new Set());
|
|
}
|
|
this.messageCallbacks.get(connectionId).add(callback);
|
|
}
|
|
/**
|
|
* Send a message to a specific connection
|
|
*/
|
|
sendMessage(connectionId, data) {
|
|
const connection = this.webSocketConnections.get(connectionId);
|
|
if (connection?.socket && connection.readyState === 1) {
|
|
try {
|
|
const message = typeof data === 'string' ? data : JSON.stringify(data);
|
|
connection.socket.send(message);
|
|
return true;
|
|
}
|
|
catch (error) {
|
|
this.log(`Failed to send message: ${error}`, 'error');
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
/**
|
|
* Example usage:
|
|
*
|
|
* // Server instance
|
|
* const serverBrain = new Brainy()
|
|
* serverBrain.augmentations.register(new APIServerAugmentation())
|
|
* await serverBrain.init()
|
|
*
|
|
* // Client instance
|
|
* const clientBrain = new Brainy()
|
|
* const conduit = new WebSocketConduitAugmentation()
|
|
* clientBrain.augmentations.register(conduit)
|
|
* await clientBrain.init()
|
|
*
|
|
* // Connect client to server
|
|
* await conduit.establishConnection('ws://localhost:3000/ws')
|
|
*
|
|
* // Now operations sync automatically!
|
|
* await clientBrain.addNoun('synced data', { source: 'client' })
|
|
* // This will automatically sync to the server
|
|
*/
|
|
//# sourceMappingURL=conduitAugmentations.js.map
|