@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
JavaScript
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
};