Files
crowd-funder-from-jason/src/services/notifications/NotificationDebugEvents.ts
T
Jose Olarte III 63f5c4ecc7 feat(notifications): add structured observability for push wake and refresh flows
Introduce NotificationDebugEvents and [Notifications] console/panel logging for push
handlers, token registration, refresh timing, schedule replacement, and WAKEUP_PING.
2026-05-18 18:46:16 +08:00

75 lines
1.9 KiB
TypeScript

/**
* Lightweight in-memory notification debug log + console observability.
* Used by production notification flows and the Notification Debug Panel.
*/
export const NOTIFICATION_LOG_PREFIX = "[Notifications]";
const MAX_ENTRIES = 100;
type LogListener = (entries: readonly string[]) => void;
const entries: string[] = [];
const listeners = new Set<LogListener>();
function formatTime(d: Date): string {
const hh = d.getHours().toString().padStart(2, "0");
const mm = d.getMinutes().toString().padStart(2, "0");
const ss = d.getSeconds().toString().padStart(2, "0");
return `${hh}:${mm}:${ss}`;
}
function formatPanelLine(message: string): string {
return `[${formatTime(new Date())}] ${message}`;
}
function notifyListeners(): void {
const snapshot = [...entries] as readonly string[];
for (const listener of listeners) {
listener(snapshot);
}
}
/** Append a timestamped line to the in-memory debug log (panel). */
export function appendLog(message: string): void {
entries.push(formatPanelLine(message));
if (entries.length > MAX_ENTRIES) {
entries.splice(0, entries.length - MAX_ENTRIES);
}
notifyListeners();
}
export function subscribe(listener: LogListener): () => void {
listeners.add(listener);
listener([...entries]);
return () => {
listeners.delete(listener);
};
}
export function clearNotificationDebugLogs(): void {
entries.length = 0;
notifyListeners();
}
export function getNotificationDebugLogEntries(): readonly string[] {
return [...entries];
}
/**
* Structured console log (`[Notifications] …`) plus debug panel entry.
*/
export function logNotification(
message: string,
detail?: Record<string, unknown>,
): void {
if (detail !== undefined) {
// eslint-disable-next-line no-console
console.log(`${NOTIFICATION_LOG_PREFIX} ${message}`, detail);
} else {
// eslint-disable-next-line no-console
console.log(`${NOTIFICATION_LOG_PREFIX} ${message}`);
}
appendLog(message);
}