Files
zn-ai/electron/api/event-bus.ts
DEV_DSW 71bcc3b3c5 feat: implement telemetry system for application usage tracking
- Added telemetry utility to capture application events and metrics.
- Integrated PostHog for event tracking with distinct user identification.
- Implemented telemetry initialization, event capturing, and shutdown procedures.

feat: add UV environment setup for Python management

- Created utilities to manage Python installation and configuration.
- Implemented network optimization checks for Python installation mirrors.
- Added functions to set up managed Python environments with error handling.

feat: enhance host API communication with token management

- Introduced host API token retrieval and management for secure requests.
- Updated host API fetch functions to include token in headers.
- Added support for creating event sources with authentication.

test: add comprehensive tests for gateway protocol and startup helpers

- Implemented unit tests for gateway protocol helpers, event dispatching, and state management.
- Added tests for startup recovery strategies and process policies.
- Ensured coverage for connection monitoring and restart governance logic.
2026-04-23 17:21:57 +08:00

65 lines
1.6 KiB
TypeScript

import type { ServerResponse } from 'node:http';
type EventPayload = unknown;
type EventListener = (payload: EventPayload) => void;
export class HostEventBus {
private readonly listeners = new Map<string, Set<EventListener>>();
private readonly sseClients = new Set<ServerResponse>();
on(eventName: string, listener: EventListener): () => void {
const bucket = this.listeners.get(eventName) ?? new Set<EventListener>();
bucket.add(listener);
this.listeners.set(eventName, bucket);
return () => {
bucket.delete(listener);
if (bucket.size === 0) {
this.listeners.delete(eventName);
}
};
}
addSseClient(res: ServerResponse): void {
this.sseClients.add(res);
res.on('close', () => {
this.sseClients.delete(res);
});
}
emit(eventName: string, payload: EventPayload): void {
const bucket = this.listeners.get(eventName);
if (bucket) {
for (const listener of bucket) {
listener(payload);
}
}
if (this.sseClients.size > 0) {
const message = `event: ${eventName}\ndata: ${JSON.stringify(payload)}\n\n`;
for (const client of this.sseClients) {
try {
client.write(message);
} catch {
this.sseClients.delete(client);
}
}
}
}
closeAll(): void {
this.listeners.clear();
for (const client of this.sseClients) {
try {
client.end();
} catch {
// Ignore individual client close failures.
}
}
this.sseClients.clear();
}
}
export const hostEventBus = new HostEventBus();