hook-engine
Version:
Production-grade webhook engine with comprehensive adapter support, security, reliability, structured logging, and CLI tools.
79 lines (78 loc) • 2.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MemoryAdapter = void 0;
/**
* In-memory storage adapter for development and testing
*/
class MemoryAdapter {
constructor(config) {
this.events = new Map();
this.seenIds = new Set();
this.config = config;
this.startCleanupTimer();
}
async isDuplicate(eventId) {
return this.seenIds.has(eventId);
}
async markSeen(eventId, metadata) {
this.seenIds.add(eventId);
if (this.events.has(eventId)) {
const event = this.events.get(eventId);
event.metadata = { ...event.metadata, ...metadata };
event.seenAt = new Date();
}
}
async storeEvent(eventId, event) {
const storedEvent = {
id: eventId,
type: event.type,
source: event.source,
timestamp: new Date(event.timestamp * 1000),
payload: event.payload,
metadata: {},
seenAt: new Date()
};
this.events.set(eventId, storedEvent);
this.seenIds.add(eventId);
}
async getEvent(eventId) {
return this.events.get(eventId) || null;
}
async cleanup() {
const now = Date.now();
const ttlMs = this.config.ttl * 1000;
for (const [eventId, event] of this.events.entries()) {
if (now - event.seenAt.getTime() > ttlMs) {
this.events.delete(eventId);
this.seenIds.delete(eventId);
}
}
}
async close() {
if (this.cleanupTimer) {
clearInterval(this.cleanupTimer);
}
this.events.clear();
this.seenIds.clear();
}
/**
* Get storage statistics
*/
getStats() {
const events = Array.from(this.events.values());
return {
totalEvents: events.length,
duplicateEvents: this.seenIds.size - events.length,
oldestEvent: events.length > 0
? new Date(Math.min(...events.map(e => e.timestamp.getTime())))
: undefined
};
}
startCleanupTimer() {
const intervalMs = this.config.cleanupInterval * 1000;
this.cleanupTimer = setInterval(() => {
this.cleanup().catch(console.error);
}, intervalMs);
}
}
exports.MemoryAdapter = MemoryAdapter;