UNPKG

@eweser/db

Version:
114 lines (99 loc) 3.46 kB
/* eslint-disable no-console -- this IS the logger implementation */ import type { EweDocument } from '@eweser/shared'; import type { Room } from './types.js'; import type { Database } from './index.js'; type EmittedEvents = Record<string | symbol, (...args: never[]) => void>; type Listener = (...args: unknown[]) => void; /** Minimal browser-compatible typed event emitter (no Node.js 'events' dependency). */ export class TypedEventEmitter<Events extends EmittedEvents> { private _listeners: Map<string | symbol, Set<Listener>> = new Map(); on<K extends keyof Events>(event: K, listener: Events[K]): this { const key = event as string | symbol; if (!this._listeners.has(key)) this._listeners.set(key, new Set()); const listeners = this._listeners.get(key); if (listeners) { listeners.add(listener as unknown as Listener); } return this; } off<K extends keyof Events>(event: K, listener: Events[K]): this { this._listeners .get(event as string | symbol) ?.delete(listener as unknown as Listener); return this; } emit<K extends keyof Events>( event: K, ...args: Parameters<Events[K]> ): boolean { const listeners = this._listeners.get(event as string | symbol); if (!listeners || listeners.size === 0) return false; listeners.forEach((l) => l(...(args as unknown[]))); return true; } once<K extends keyof Events>(event: K, listener: Events[K]): this { const wrapper: Listener = (...args) => { this.off(event, listener); (listener as unknown as Listener)(...args); }; return this.on(event, wrapper as unknown as Events[K]); } removeAllListeners<K extends keyof Events>(event?: K): this { if (event !== undefined) { this._listeners.delete(event as string | symbol); } else { this._listeners.clear(); } return this; } } export type RoomConnectionStatus = 'connected' | 'disconnected' | 'connecting'; export type DatabaseEvents = { log: (level: number, ...args: unknown[]) => void; debug: (...args: unknown[]) => void; info: (...args: unknown[]) => void; warn: (...args: unknown[]) => void; error: (...args: unknown[]) => void; roomLoaded: (room: Room<EweDocument>) => void; roomRemoteLoaded: (room: Room<EweDocument>) => void; roomsLoaded: (rooms: Room<EweDocument>[]) => void; roomsRemotesLoaded: (rooms: Room<EweDocument>[]) => void; roomConnectionChange: ( status: RoomConnectionStatus, room: Room<EweDocument> ) => void; onLoggedInChange: (loggedIn: boolean) => void; onlineChange: (online: boolean) => void; status: (status: { db: Database; online: boolean; hasToken: boolean; allRoomsCount: number; connectedRoomsCount: number; connectedRooms: string[]; connectingRoomsCount: number; connectingRooms: string[]; }) => void; registrySync: ( status: 'syncing' | 'success' | 'error', error?: unknown ) => void; initialized: () => void; }; export type RoomEvents<T extends EweDocument> = { roomConnectionChange: (status: RoomConnectionStatus, room: Room<T>) => void; }; export const setupLogger = (db: Database) => { db.on('log', (level, ...message) => { switch (level) { case 0: return console.info(...message); case 1: return console.log(...message); case 2: return console.warn(...message); case 3: return console.error(...message); } }); };