ByteBrief / src /firebase /error-emitter.ts
Gigishot's picture
Upload 68 files
78aa7cb verified
Raw
History Blame Contribute Delete
2.12 kB
'use client';
import { FirestorePermissionError } from '@/firebase/errors';
/**
* Defines the shape of all possible events and their corresponding payload types.
* This centralizes event definitions for type safety across the application.
*/
export interface AppEvents {
'permission-error': FirestorePermissionError;
}
// A generic type for a callback function.
type Callback<T> = (data: T) => void;
/**
* A strongly-typed pub/sub event emitter.
* It uses a generic type T that extends a record of event names to payload types.
*/
function createEventEmitter<T extends Record<string, any>>() {
// The events object stores arrays of callbacks, keyed by event name.
// The types ensure that a callback for a specific event matches its payload type.
const events: { [K in keyof T]?: Array<Callback<T[K]>> } = {};
return {
/**
* Subscribe to an event.
* @param eventName The name of the event to subscribe to.
* @param callback The function to call when the event is emitted.
*/
on<K extends keyof T>(eventName: K, callback: Callback<T[K]>) {
if (!events[eventName]) {
events[eventName] = [];
}
events[eventName]?.push(callback);
},
/**
* Unsubscribe from an event.
* @param eventName The name of the event to unsubscribe from.
* @param callback The specific callback to remove.
*/
off<K extends keyof T>(eventName: K, callback: Callback<T[K]>) {
if (!events[eventName]) {
return;
}
events[eventName] = events[eventName]?.filter(cb => cb !== callback);
},
/**
* Publish an event to all subscribers.
* @param eventName The name of the event to emit.
* @param data The data payload that corresponds to the event's type.
*/
emit<K extends keyof T>(eventName: K, data: T[K]) {
if (!events[eventName]) {
return;
}
events[eventName]?.forEach(callback => callback(data));
},
};
}
// Create and export a singleton instance of the emitter, typed with our AppEvents interface.
export const errorEmitter = createEventEmitter<AppEvents>();