UNPKG

@stackmemoryai/stackmemory

Version:

Lossless, project-scoped memory for AI coding tools. Durable context across sessions with 56 MCP tools, FTS5 search, conductor orchestrator, loop/watch monitoring, snapshot capture, pre-flight overlap checks, Claude/Codex/OpenCode wrappers, Linear sync, a

58 lines (57 loc) 1.62 kB
import { fileURLToPath as __fileURLToPath } from 'url'; import { dirname as __pathDirname } from 'path'; const __filename = __fileURLToPath(import.meta.url); const __dirname = __pathDirname(__filename); import { EventEmitter } from "events"; class HookEventEmitter extends EventEmitter { handlers = /* @__PURE__ */ new Map(); registerHandler(eventType, handler) { if (!this.handlers.has(eventType)) { this.handlers.set(eventType, /* @__PURE__ */ new Set()); } const handlers = this.handlers.get(eventType); if (handlers) { handlers.add(handler); } this.on(eventType, handler); } unregisterHandler(eventType, handler) { const handlers = this.handlers.get(eventType); if (handlers) { handlers.delete(handler); this.off(eventType, handler); } } async emitHook(event) { const handlers = this.handlers.get(event.type); if (!handlers || handlers.size === 0) { return; } const promises = []; for (const handler of handlers) { try { const result = handler(event); if (result instanceof Promise) { promises.push(result); } } catch (error) { this.emit("error", { type: "error", timestamp: Date.now(), data: { error, originalEvent: event } }); } } await Promise.allSettled(promises); } getRegisteredEvents() { return Array.from(this.handlers.keys()).filter( (type) => (this.handlers.get(type)?.size ?? 0) > 0 ); } } const hookEmitter = new HookEventEmitter(); export { HookEventEmitter, hookEmitter };