anon-identity
Version:
Decentralized identity framework with DIDs, Verifiable Credentials, and privacy-preserving selective disclosure
158 lines • 5.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DirectChannel = void 0;
/**
* Direct communication channel for same-process agent communication
* Useful for testing and same-application agent interactions
*/
class DirectChannel {
constructor(id, options = {}) {
this.type = 'direct';
this.isConnected = false;
this.messageHandlers = new Set();
this.id = id;
this.options = {
deliveryDelay: options.deliveryDelay || 0,
reliability: options.reliability || 1.0,
enableLogging: options.enableLogging || false
};
// Register this channel
DirectChannel.channels.set(id, this);
}
async connect() {
this.isConnected = true;
if (this.options.enableLogging) {
console.log(`Direct channel ${this.id} connected`);
}
}
async disconnect() {
this.isConnected = false;
DirectChannel.channels.delete(this.id);
if (this.options.enableLogging) {
console.log(`Direct channel ${this.id} disconnected`);
}
}
async send(envelope) {
if (!this.isConnected) {
throw new Error('Channel not connected');
}
// Simulate network reliability
if (Math.random() > this.options.reliability) {
throw new Error('Message delivery failed (simulated network issue)');
}
// Extract recipient from message
const recipientDID = envelope.message.to;
const recipientChannel = this.findChannelForAgent(recipientDID);
if (!recipientChannel) {
throw new Error(`No direct channel found for recipient: ${recipientDID}`);
}
// Simulate network delay
const deliverMessage = () => {
if (recipientChannel.isConnected) {
recipientChannel.deliverMessage(envelope);
}
else {
if (this.options.enableLogging) {
console.warn(`Recipient channel ${recipientChannel.id} not connected, dropping message`);
}
}
};
if (this.options.deliveryDelay > 0) {
setTimeout(deliverMessage, this.options.deliveryDelay);
}
else {
deliverMessage();
}
}
onMessage(handler) {
this.messageHandlers.add(handler);
}
removeMessageHandler(handler) {
this.messageHandlers.delete(handler);
}
deliverMessage(envelope) {
if (this.options.enableLogging) {
console.log(`Direct channel ${this.id} received message:`, envelope.message.type);
}
// Deliver to all handlers
this.messageHandlers.forEach(handler => {
try {
handler(envelope);
}
catch (error) {
console.error('Message handler error:', error);
}
});
}
findChannelForAgent(agentDID) {
// In a real implementation, you'd have a registry mapping agents to channels
// For simplicity, we'll assume channel ID matches agent DID or use a simple lookup
// First try exact match
let channel = DirectChannel.channels.get(agentDID);
if (channel)
return channel;
// Try to find by some other mapping logic
// For now, return the first available channel (for testing)
for (const [id, ch] of DirectChannel.channels.entries()) {
if (id !== this.id && ch.isConnected) {
return ch;
}
}
return undefined;
}
// Static methods for managing direct channels
static getChannel(id) {
return this.channels.get(id);
}
static getAllChannels() {
return Array.from(this.channels.values());
}
static getConnectedChannels() {
return this.getAllChannels().filter(ch => ch.isConnected);
}
static createChannelPair(id1, id2) {
const channel1 = new DirectChannel(id1);
const channel2 = new DirectChannel(id2);
return [channel1, channel2];
}
static async broadcastToAll(envelope, excludeId) {
const channels = this.getConnectedChannels();
let delivered = 0;
for (const channel of channels) {
if (excludeId && channel.id === excludeId)
continue;
try {
await channel.send(envelope);
delivered++;
}
catch (error) {
console.error(`Broadcast failed to ${channel.id}:`, error);
}
}
return delivered;
}
// Utility methods for testing and debugging
getStats() {
return {
id: this.id,
connected: this.isConnected,
handlerCount: this.messageHandlers.size,
options: this.options
};
}
static getGlobalStats() {
const allChannels = this.getAllChannels();
return {
totalChannels: allChannels.length,
connectedChannels: allChannels.filter(ch => ch.isConnected).length,
channels: allChannels.map(ch => ({
id: ch.id,
connected: ch.isConnected,
handlerCount: ch.messageHandlers.size
}))
};
}
}
exports.DirectChannel = DirectChannel;
DirectChannel.channels = new Map();
//# sourceMappingURL=direct-channel.js.map