Merge pull request #973 from PR0M3TH3AN/codex/mute-console-logs-for-count-request

Add verbose dev mode toggle for COUNT warnings
This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2025-10-27 15:21:57 -04:00
commit 01a7877e97
7 files changed
+199 -17

No files matched your search

+9
View File
@@ -23,6 +23,15 @@
*/
export const IS_DEV_MODE = true;
/**
* Whether development builds should surface extra verbose diagnostics.
*
* Set this to `true` to keep high-volume development warnings (like COUNT
* request failures) visible in the console. Flip it to `false` when you want
* a quieter dev mode without disabling other development helpers entirely.
*/
export const IS_VERBOSE_DEV_MODE = false;
/**
* Whether the current deployment should operate in lockdown mode.
*
+5
View File
@@ -3,6 +3,7 @@
import { userLogger } from "./utils/logger.js";
import {
IS_DEV_MODE,
IS_VERBOSE_DEV_MODE,
IS_LOCKDOWN_MODE,
ADMIN_SUPER_NPUB,
ADMIN_DM_IMAGE_URL,
@@ -43,11 +44,15 @@ import {
export const isDevMode = Boolean(IS_DEV_MODE);
export { IS_DEV_MODE };
export const isVerboseDevMode = Boolean(IS_VERBOSE_DEV_MODE);
export { IS_VERBOSE_DEV_MODE };
export const isLockdownMode = Boolean(IS_LOCKDOWN_MODE);
export { IS_LOCKDOWN_MODE };
if (typeof window !== "undefined") {
window.__BITVID_DEV_MODE__ = isDevMode;
window.__BITVID_VERBOSE_DEV_MODE__ = isVerboseDevMode;
window.__BITVID_LOCKDOWN_MODE__ = isLockdownMode;
}
+14 -12
View File
@@ -58,6 +58,11 @@ import {
listVideoComments as listVideoCommentsForClient,
subscribeVideoComments as subscribeVideoCommentsForClient,
} from "./commentEvents.js";
import {
logCountTimeoutCleanupFailure,
logRelayCountFailure,
} from "./countDiagnostics.js";
import "./maxListenerDiagnostics.js";
import {
publishEventToRelay,
publishEventToRelays,
@@ -345,7 +350,7 @@ function withRequestTimeout(promise, timeoutMs, onTimeout, message = "Request ti
try {
onTimeout();
} catch (cleanupError) {
devLogger.warn("[nostr] COUNT timeout cleanup failed:", cleanupError);
logCountTimeoutCleanupFailure(cleanupError);
}
}
reject(new Error(message));
@@ -5739,18 +5744,15 @@ export class NostrClient {
});
const count = this.extractCountValue(frame?.[2]);
return { url, ok: true, frame, count };
} catch (error) {
const isUnsupported = error?.code === "count-unsupported";
if (isUnsupported) {
this.countUnsupportedRelays.add(url);
} else {
devLogger.warn(
`[nostr] COUNT request failed on ${url}:`,
error,
);
}
return { url, ok: false, error, unsupported: isUnsupported };
} catch (error) {
const isUnsupported = error?.code === "count-unsupported";
if (isUnsupported) {
this.countUnsupportedRelays.add(url);
} else {
logRelayCountFailure(url, error);
}
return { url, ok: false, error, unsupported: isUnsupported };
}
})
);
+65
View File
@@ -0,0 +1,65 @@
// js/nostr/countDiagnostics.js
// Centralized helpers for gating high-volume COUNT diagnostics (and other
// verbose nostr warnings) behind verbose dev mode while deduplicating repeated
// messages so the console stays readable during normal development sessions.
import { devLogger } from "../utils/logger.js";
import { isVerboseDevMode } from "../config.js";
const seenWarningKeys = new Set();
export function isVerboseDiagnosticsEnabled() {
if (typeof window !== "undefined" && window) {
const runtimeFlag = window.__BITVID_VERBOSE_DEV_MODE__;
if (typeof runtimeFlag === "boolean") {
return runtimeFlag;
}
}
return Boolean(isVerboseDevMode);
}
function logCountWarning(message, args = [], { key, throttle = true } = {}) {
if (!isVerboseDiagnosticsEnabled()) {
return;
}
if (throttle && key) {
const normalizedKey = String(key);
if (seenWarningKeys.has(normalizedKey)) {
return;
}
seenWarningKeys.add(normalizedKey);
}
devLogger.warn(message, ...args);
}
export function logCountTimeoutCleanupFailure(error) {
logCountWarning("[nostr] COUNT timeout cleanup failed:", [error], {
key: "count-timeout-cleanup",
});
}
export function logRelayCountFailure(url, error) {
const normalizedUrl =
typeof url === "string" && url.trim() ? url.trim() : "(unknown relay)";
logCountWarning(`[nostr] COUNT request failed on ${normalizedUrl}:`, [error], {
key: `relay:${normalizedUrl}`,
});
}
export function logRebroadcastCountFailure(error) {
logCountWarning("[nostr] COUNT request for rebroadcast failed:", [error], {
key: "rebroadcast-count-failure",
});
}
export function logViewCountFailure(error) {
logCountWarning("[nostr] COUNT view request failed:", [error], {
key: "view-count-failure",
});
}
export function resetCountWarningHistory() {
seenWarningKeys.clear();
}
+101
View File
@@ -0,0 +1,101 @@
// js/nostr/maxListenerDiagnostics.js
// Suppresses noisy MaxListenersExceededWarning diagnostics unless verbose
// dev mode is enabled by shimming `process.emitWarning`. The EventEmitter
// polyfill used by nostr-tools surfaces listener leaks through
// `process.emitWarning`, so we intercept that hook instead of importing the
// Node `events` module (which breaks browser bundlers) or rewriting
// console.warn globally.
import { isVerboseDiagnosticsEnabled } from "./countDiagnostics.js";
const MAX_LISTENER_SNIPPETS = [
"MaxListenersExceededWarning",
"Possible EventEmitter memory leak detected",
];
const MAX_LISTENER_CODES = new Set(["MaxListenersExceededWarning"]);
function collectCandidateStrings(value) {
const candidates = [];
if (!value) {
return candidates;
}
if (typeof value === "string") {
candidates.push(value);
return candidates;
}
if (typeof value === "object") {
const fields = ["name", "message", "code", "type"];
for (const field of fields) {
const fieldValue = value[field];
if (typeof fieldValue === "string") {
candidates.push(fieldValue);
}
}
}
return candidates;
}
function shouldSuppressWarning(...args) {
if (isVerboseDiagnosticsEnabled()) {
return false;
}
const candidates = [];
for (const arg of args) {
candidates.push(...collectCandidateStrings(arg));
}
for (const candidate of candidates) {
if (MAX_LISTENER_CODES.has(candidate)) {
return true;
}
if (MAX_LISTENER_SNIPPETS.some((snippet) => candidate.includes(snippet))) {
return true;
}
}
return false;
}
function patchProcessEmitWarning() {
const processRef =
typeof globalThis !== "undefined" && globalThis
? globalThis.process
: typeof process !== "undefined"
? process
: undefined;
if (!processRef || typeof processRef.emitWarning !== "function") {
return;
}
const originalEmitWarning = processRef.emitWarning.bind(processRef);
if (processRef.emitWarning.__BITVID_MAX_LISTENER_PATCHED__) {
return;
}
function patchedEmitWarning(warning, ...rest) {
if (shouldSuppressWarning(warning, ...rest)) {
return;
}
return originalEmitWarning(warning, ...rest);
}
patchedEmitWarning.__BITVID_MAX_LISTENER_PATCHED__ = true;
processRef.emitWarning = patchedEmitWarning;
}
patchProcessEmitWarning();
export function refreshMaxListenerPreference() {
// The shim dynamically checks the verbose flag on each invocation, so there
// is nothing else to refresh right now. This placeholder remains for API
// parity if runtime toggling ever requires additional work.
}
+3 -4
View File
@@ -1,6 +1,4 @@
import {
ENSURE_PRESENCE_REBROADCAST_COOLDOWN_SECONDS,
} from "../config.js";
import { ENSURE_PRESENCE_REBROADCAST_COOLDOWN_SECONDS } from "../config.js";
import {
publishEventToRelays,
assertAnyRelayAccepted,
@@ -16,6 +14,7 @@ import {
} from "./toolkit.js";
import { DEFAULT_NIP07_PERMISSION_METHODS } from "./nip07Permissions.js";
import { devLogger, userLogger } from "../utils/logger.js";
import { logRebroadcastCountFailure } from "./countDiagnostics.js";
const REBROADCAST_GUARD_PREFIX = "bitvid:rebroadcast:v1";
const rebroadcastAttemptMemory = new Map();
@@ -1023,7 +1022,7 @@ export async function rebroadcastEvent({ client, eventId, options = {} }) {
})
: null;
} catch (error) {
devLogger.warn("[nostr] COUNT request for rebroadcast failed:", error);
logRebroadcastCountFailure(error);
}
if (countResult?.total && Number(countResult.total) > 0) {
+2 -1
View File
@@ -12,6 +12,7 @@ import { publishEventToRelay } from "../nostrPublish.js";
import { RELAY_URLS } from "./toolkit.js";
import { normalizePointerInput } from "./watchHistory.js";
import { devLogger, userLogger } from "../utils/logger.js";
import { logViewCountFailure } from "./countDiagnostics.js";
const VIEW_EVENT_GUARD_PREFIX = "bitvid:viewed";
@@ -590,7 +591,7 @@ export async function countVideoViewEvents(client, pointer, options = {}) {
}
} catch (error) {
if (error?.code !== "count-unsupported") {
devLogger.warn("[nostr] COUNT view request failed:", error);
logViewCountFailure(error);
}
}