@454creative/easy-events
Version:
A minimal event engine for Node.js and NestJS, wrapping Emmett for lightweight in-process event handling
197 lines • 6.71 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createStorageEngine = exports.DatabaseStorageEngine = exports.FileStorageEngine = exports.MemoryStorageEngine = void 0;
const promises_1 = __importDefault(require("fs/promises"));
const path_1 = __importDefault(require("path"));
// In-Memory Storage (current implementation)
class MemoryStorageEngine {
constructor() {
this.auditLogs = [];
this.metrics = {
totalEvents: 0,
eventsByType: {},
averageProcessingTime: 0,
errorCount: 0,
activeHandlers: 0,
};
}
async saveAuditLog(audit) {
this.auditLogs.push(audit);
}
async getAuditLogs(filters) {
let logs = [...this.auditLogs];
if (filters) {
logs = logs.filter((log) => {
return Object.entries(filters).every(([key, value]) => {
return log[key] === value;
});
});
}
return logs;
}
async saveMetrics(metrics) {
this.metrics = { ...metrics };
}
async getMetrics() {
return { ...this.metrics };
}
async clearAuditLogs() {
this.auditLogs = [];
}
async clearMetrics() {
this.metrics = {
totalEvents: 0,
eventsByType: {},
averageProcessingTime: 0,
errorCount: 0,
activeHandlers: 0,
};
}
}
exports.MemoryStorageEngine = MemoryStorageEngine;
// File Storage Engine
class FileStorageEngine {
constructor(config) {
const basePath = config.path || "./easy-events-data";
this.auditLogsPath = path_1.default.join(basePath, "audit-logs.jsonl");
this.metricsPath = path_1.default.join(basePath, "metrics.json");
this.maxLogs = config.maxLogs || 10000;
}
async saveAuditLog(audit) {
try {
await promises_1.default.mkdir(path_1.default.dirname(this.auditLogsPath), { recursive: true });
const logLine = JSON.stringify(audit) + "\n";
await promises_1.default.appendFile(this.auditLogsPath, logLine);
// Implement log rotation
await this.rotateLogs();
}
catch (error) {
console.warn("Failed to save audit log to file:", error);
}
}
async getAuditLogs(filters) {
try {
const content = await promises_1.default.readFile(this.auditLogsPath, "utf-8");
const logs = content
.trim()
.split("\n")
.map((line) => JSON.parse(line));
if (filters) {
return logs.filter((log) => {
return Object.entries(filters).every(([key, value]) => {
return log[key] === value;
});
});
}
return logs;
}
catch (error) {
return [];
}
}
async saveMetrics(metrics) {
try {
await promises_1.default.mkdir(path_1.default.dirname(this.metricsPath), { recursive: true });
await promises_1.default.writeFile(this.metricsPath, JSON.stringify(metrics, null, 2));
}
catch (error) {
console.warn("Failed to save metrics to file:", error);
}
}
async getMetrics() {
try {
const content = await promises_1.default.readFile(this.metricsPath, "utf-8");
return JSON.parse(content);
}
catch (error) {
return {
totalEvents: 0,
eventsByType: {},
averageProcessingTime: 0,
errorCount: 0,
activeHandlers: 0,
};
}
}
async clearAuditLogs() {
try {
await promises_1.default.unlink(this.auditLogsPath);
}
catch (error) {
// File doesn't exist, that's fine
}
}
async clearMetrics() {
try {
await promises_1.default.unlink(this.metricsPath);
}
catch (error) {
// File doesn't exist, that's fine
}
}
async rotateLogs() {
try {
const content = await promises_1.default.readFile(this.auditLogsPath, "utf-8");
const lines = content.trim().split("\n");
if (lines.length > this.maxLogs) {
const rotatedLines = lines.slice(-this.maxLogs);
await promises_1.default.writeFile(this.auditLogsPath, rotatedLines.join("\n") + "\n");
}
}
catch (error) {
// Ignore rotation errors
}
}
}
exports.FileStorageEngine = FileStorageEngine;
// Database Storage Engine (example with SQLite)
class DatabaseStorageEngine {
constructor(_config) {
// this.dbPath = _config.connectionString || './easy-events.db';
}
async saveAuditLog(audit) {
// This would use a real database like SQLite, PostgreSQL, etc.
// For now, we'll use file storage as a simple database
const fileEngine = new FileStorageEngine({ type: "file", path: "./db" });
await fileEngine.saveAuditLog(audit);
}
async getAuditLogs(filters) {
const fileEngine = new FileStorageEngine({ type: "file", path: "./db" });
return fileEngine.getAuditLogs(filters);
}
async saveMetrics(metrics) {
const fileEngine = new FileStorageEngine({ type: "file", path: "./db" });
await fileEngine.saveMetrics(metrics);
}
async getMetrics() {
const fileEngine = new FileStorageEngine({ type: "file", path: "./db" });
return fileEngine.getMetrics();
}
async clearAuditLogs() {
const fileEngine = new FileStorageEngine({ type: "file", path: "./db" });
await fileEngine.clearAuditLogs();
}
async clearMetrics() {
const fileEngine = new FileStorageEngine({ type: "file", path: "./db" });
await fileEngine.clearMetrics();
}
}
exports.DatabaseStorageEngine = DatabaseStorageEngine;
// Storage Factory
function createStorageEngine(config) {
switch (config.type) {
case "memory":
return new MemoryStorageEngine();
case "file":
return new FileStorageEngine(config);
case "database":
return new DatabaseStorageEngine(config);
default:
return new MemoryStorageEngine();
}
}
exports.createStorageEngine = createStorageEngine;
//# sourceMappingURL=storage-engines.js.map