fortify2-js
Version:
MOST POWERFUL JavaScript Security Library! Military-grade cryptography + 19 enhanced object methods + quantum-resistant algorithms + perfect TypeScript support. More powerful than Lodash with built-in security.
278 lines (274 loc) • 7.47 kB
JavaScript
'use strict';
var types = require('./types.js');
/**
* Memory Event Manager
*
* Handles all memory-related events with filtering, history, and error handling
*/
/**
* Event manager for memory events with advanced features
*/
class MemoryEventManager {
constructor(config) {
this.listeners = new Map();
this.eventHistory = [];
this.filters = new Set();
this.isEnabled = true;
this.eventCounts = new Map();
this.maxHistorySize = config.maxEventHistory;
}
/**
* Add event listener
*/
on(type, listener) {
if (!this.listeners.has(type)) {
this.listeners.set(type, new Set());
}
this.listeners.get(type).add(listener);
}
/**
* Add event listener for multiple types
*/
onMultiple(types, listener) {
types.forEach(type => this.on(type, listener));
}
/**
* Add one-time event listener
*/
once(type, listener) {
const onceWrapper = (event) => {
listener(event);
this.off(type, onceWrapper);
};
this.on(type, onceWrapper);
}
/**
* Remove event listener
*/
off(type, listener) {
const listeners = this.listeners.get(type);
if (listeners) {
listeners.delete(listener);
if (listeners.size === 0) {
this.listeners.delete(type);
}
}
}
/**
* Remove all listeners for a type
*/
removeAllListeners(type) {
if (type) {
this.listeners.delete(type);
}
else {
this.listeners.clear();
}
}
/**
* Add event filter
*/
addFilter(filter) {
this.filters.add(filter);
}
/**
* Remove event filter
*/
removeFilter(filter) {
this.filters.delete(filter);
}
/**
* Clear all filters
*/
clearFilters() {
this.filters.clear();
}
/**
* Enable/disable event manager
*/
setEnabled(enabled) {
this.isEnabled = enabled;
}
/**
* Check if event passes all filters
*/
passesFilters(event) {
for (const filter of this.filters) {
try {
if (!filter(event)) {
return false;
}
}
catch (error) {
console.error('Error in event filter:', error);
// Continue with other filters
}
}
return true;
}
/**
* Emit event with comprehensive error handling
*/
emit(type, data, metadata) {
if (!this.isEnabled) {
return;
}
const event = {
type,
timestamp: Date.now(),
data,
metadata: {
...metadata,
eventId: this.generateEventId(),
sequence: this.getEventCount(type)
}
};
// Apply filters
if (!this.passesFilters(event)) {
return;
}
// Update event count
this.eventCounts.set(type, (this.eventCounts.get(type) || 0) + 1);
// Add to history
this.addToHistory(event);
// Notify listeners
this.notifyListeners(type, event);
}
/**
* Add event to history with size management
*/
addToHistory(event) {
this.eventHistory.push(event);
// Maintain history size
while (this.eventHistory.length > this.maxHistorySize) {
this.eventHistory.shift();
}
}
/**
* Notify all listeners for an event type
*/
notifyListeners(type, event) {
const listeners = this.listeners.get(type);
if (!listeners || listeners.size === 0) {
return;
}
// Create array to avoid modification during iteration
const listenerArray = Array.from(listeners);
for (const listener of listenerArray) {
try {
listener(event);
}
catch (error) {
console.error(`Error in memory event listener for ${type}:`, error);
// Emit error event (but avoid infinite loops)
if (type !== types.MemoryEventType.ERROR_OCCURRED) {
this.emit(types.MemoryEventType.ERROR_OCCURRED, {
originalEvent: event,
error: error instanceof Error ? error.message : String(error),
listenerError: true
});
}
}
}
}
/**
* Generate unique event ID
*/
generateEventId() {
return `evt_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
/**
* Get event count for a type
*/
getEventCount(type) {
return this.eventCounts.get(type) || 0;
}
/**
* Get event history with optional filtering
*/
getHistory(type, limit) {
let events = type
? this.eventHistory.filter(event => event.type === type)
: [...this.eventHistory];
if (limit && limit > 0) {
events = events.slice(-limit);
}
return events;
}
/**
* Get event statistics
*/
getEventStats() {
const stats = {
totalEvents: this.eventHistory.length,
eventCounts: Object.fromEntries(this.eventCounts),
activeListeners: this.listeners.size,
activeFilters: this.filters.size,
isEnabled: this.isEnabled,
historySize: this.eventHistory.length,
maxHistorySize: this.maxHistorySize
};
// Calculate event frequency (events per minute)
if (this.eventHistory.length > 1) {
const firstEvent = this.eventHistory[0];
const lastEvent = this.eventHistory[this.eventHistory.length - 1];
const timeSpan = lastEvent.timestamp - firstEvent.timestamp;
stats.eventsPerMinute = (this.eventHistory.length / timeSpan) * 60000;
}
return stats;
}
/**
* Clear event history
*/
clearHistory() {
this.eventHistory = [];
}
/**
* Clear event counts
*/
clearEventCounts() {
this.eventCounts.clear();
}
/**
* Update configuration
*/
updateConfig(config) {
if (config.maxEventHistory !== undefined) {
this.maxHistorySize = config.maxEventHistory;
// Trim history if needed
while (this.eventHistory.length > this.maxHistorySize) {
this.eventHistory.shift();
}
}
}
/**
* Get listener count for a specific event type
*/
getListenerCount(type) {
return this.listeners.get(type)?.size || 0;
}
/**
* Check if there are any listeners for an event type
*/
hasListeners(type) {
return this.getListenerCount(type) > 0;
}
/**
* Get all registered event types
*/
getRegisteredEventTypes() {
return Array.from(this.listeners.keys());
}
/**
* Destroy the event manager
*/
destroy() {
this.listeners.clear();
this.eventHistory = [];
this.filters.clear();
this.eventCounts.clear();
this.isEnabled = false;
}
}
exports.MemoryEventManager = MemoryEventManager;
//# sourceMappingURL=event-manager.js.map