react-native-unit-components
Version:
Unit React Native components
101 lines (91 loc) • 2.5 kB
JavaScript
// Type-safe callback that receives the correct data type for the event key
class EventBus {
debug = false;
listeners = new Map();
eventQueue = [];
isProcessing = false;
/**
* Subscribe to an event
* @returns Unsubscribe function
*/
on(eventKey, callback) {
if (!this.listeners.has(eventKey)) {
this.listeners.set(eventKey, new Set());
}
this.listeners.get(eventKey).add(callback);
if (this.debug) {
console.log(`[EventBus] Subscribed to: ${eventKey} (${this.listenerCount(eventKey)} listeners)`);
}
// Return unsubscribe function
return () => {
const callbacks = this.listeners.get(eventKey);
if (callbacks) {
callbacks.delete(callback);
if (callbacks.size === 0) {
this.listeners.delete(eventKey);
}
}
};
}
/**
* Emit an event - queues it for processing to ensure all events are delivered
*/
emit(eventKey, data) {
const event = {
key: eventKey,
data
};
if (this.debug) {
console.log(`[EventBus] Emitting: ${eventKey} (${this.listenerCount(eventKey)} listeners)`);
}
this.eventQueue.push(event);
this.processQueue();
}
/**
* Process events from queue sequentially
* This ensures rapid successive events are all delivered
*/
processQueue() {
if (this.isProcessing || this.eventQueue.length === 0) {
return;
}
this.isProcessing = true;
// Process all queued events synchronously to ensure immediate delivery
while (this.eventQueue.length > 0) {
const event = this.eventQueue.shift();
const callbacks = this.listeners.get(event.key);
if (callbacks && callbacks.size > 0) {
// Process all listeners for this event
callbacks.forEach(callback => {
try {
callback(event.data);
} catch (error) {
console.error(`Error in event listener for ${event.key}:`, error);
}
});
}
}
this.isProcessing = false;
}
/**
* Remove all listeners for an event
*/
off(eventKey) {
this.listeners.delete(eventKey);
}
/**
* Get number of listeners for an event (useful for debugging)
*/
listenerCount(eventKey) {
return this.listeners.get(eventKey)?.size ?? 0;
}
/**
* Enable or disable debug logging
*/
setDebug(enabled) {
this.debug = enabled;
}
}
// Singleton instance
export const eventBus = new EventBus();
//# sourceMappingURL=EventBus.js.map