mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Merge pull request #573 from PR0M3TH3AN/codex/refactor-logging-to-use-logger-module
Refactor JS logging to use shared loggers
This commit is contained in:
54 files changed
+940
-1197
No files matched your search
+2
-1
@@ -8,6 +8,7 @@ import {
|
||||
ADMIN_WHITELIST_MODE_STORAGE_KEY,
|
||||
} from "./config.js";
|
||||
import { loadAdminState, persistAdminState } from "./adminListStore.js";
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
|
||||
function normalizeNpub(value) {
|
||||
return typeof value === "string" ? value.trim() : "";
|
||||
@@ -126,7 +127,7 @@ class AccessControl {
|
||||
|
||||
const operation = this._performRefresh();
|
||||
const tracked = operation.catch((error) => {
|
||||
console.error("Failed to refresh admin lists:", error);
|
||||
userLogger.error("Failed to refresh admin lists:", error);
|
||||
throw error;
|
||||
});
|
||||
this._refreshPromise = tracked;
|
||||
|
||||
+25
-38
@@ -9,6 +9,7 @@ import {
|
||||
} from "./config.js";
|
||||
import { nostrClient } from "./nostr.js";
|
||||
import {
|
||||
import { devLogger, userLogger } from "./utils/logger.js";
|
||||
buildAdminListEvent,
|
||||
ADMIN_LIST_IDENTIFIERS,
|
||||
} from "./nostrEventSchemas.js";
|
||||
@@ -150,8 +151,7 @@ function readJsonListFromStorage(key) {
|
||||
const parsed = JSON.parse(raw);
|
||||
return Array.isArray(parsed) ? parsed : null;
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(`[adminListStore] Failed to parse legacy list for ${key}:`, error);
|
||||
devLogger.warn(`[adminListStore] Failed to parse legacy list for ${key:`, error);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -198,8 +198,7 @@ function clearLegacyStorageFor(listKey) {
|
||||
try {
|
||||
localStorage.removeItem(key);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(`[adminListStore] Failed to clear legacy storage for ${key}:`, error);
|
||||
devLogger.warn(`[adminListStore] Failed to clear legacy storage for ${key:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,9 +243,7 @@ function encodeHexToNpub(hex) {
|
||||
try {
|
||||
return window?.NostrTools?.nip19?.npubEncode(hex) || "";
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn("Failed to encode hex pubkey to npub:", error);
|
||||
}
|
||||
devLogger.warn("Failed to encode hex pubkey to npub:", error);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -333,12 +330,10 @@ async function loadNostrList(identifier) {
|
||||
events = combined;
|
||||
}
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
`[adminListStore] Combined relay fetch failed for ${identifier}:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
`[adminListStore] Combined relay fetch failed for ${identifier}:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
|
||||
if (!events.length) {
|
||||
@@ -348,12 +343,10 @@ async function loadNostrList(identifier) {
|
||||
const result = await nostrClient.pool.list([url], [filter]);
|
||||
return Array.isArray(result) ? result : [];
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
`[adminListStore] Relay fetch failed for ${identifier} on ${url}:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
`[adminListStore] Relay fetch failed for ${identifier} on ${url}:`,
|
||||
error
|
||||
);
|
||||
return [];
|
||||
}
|
||||
})
|
||||
@@ -394,12 +387,10 @@ function buildListEvent(listKey, npubs, actorHex) {
|
||||
try {
|
||||
return decodeNpubToHex(npub);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
`[adminListStore] Failed to decode npub while publishing ${listKey}:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
`[adminListStore] Failed to decode npub while publishing ${listKey}:`,
|
||||
error
|
||||
);
|
||||
return "";
|
||||
}
|
||||
}).filter((hex) => !!hex))
|
||||
@@ -412,9 +403,7 @@ function buildListEvent(listKey, npubs, actorHex) {
|
||||
hexPubkeys.push(superHex);
|
||||
}
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn("Failed to ensure super admin presence:", error);
|
||||
}
|
||||
devLogger.warn("Failed to ensure super admin presence:", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,12 +446,10 @@ function publishToRelay(url, signedEvent, listKey) {
|
||||
pub.on(eventName, handler);
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
`[adminListStore] Relay publish rejected ${eventName} listener:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
`[adminListStore] Relay publish rejected ${eventName} listener:`,
|
||||
error
|
||||
);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -500,7 +487,7 @@ function publishToRelay(url, signedEvent, listKey) {
|
||||
finalize(true);
|
||||
}).then((result) => {
|
||||
if (!result.success && isDevMode) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
`[adminListStore] Publish failed for ${listKey} on ${result.url}:`,
|
||||
result.error
|
||||
);
|
||||
@@ -605,7 +592,7 @@ async function persistNostrState(actorNpub, updates = {}) {
|
||||
|
||||
export async function loadAdminState() {
|
||||
if (ADMIN_LIST_MODE !== "nostr" && isDevMode) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
`[adminListStore] ADMIN_LIST_MODE "${ADMIN_LIST_MODE}" is deprecated. Defaulting to remote Nostr lists.`
|
||||
);
|
||||
}
|
||||
@@ -614,7 +601,7 @@ export async function loadAdminState() {
|
||||
if (!hasAnyEntries(state)) {
|
||||
const legacy = loadLegacyAdminState();
|
||||
if (legacy && isDevMode) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[adminListStore] Ignoring legacy admin lists because remote mode is enforced. Publish them to Nostr to retain access.",
|
||||
legacy
|
||||
);
|
||||
@@ -626,7 +613,7 @@ export async function loadAdminState() {
|
||||
|
||||
export async function persistAdminState(actorNpub, updates) {
|
||||
if (ADMIN_LIST_MODE !== "nostr" && isDevMode) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
`[adminListStore] ADMIN_LIST_MODE "${ADMIN_LIST_MODE}" is deprecated. Remote lists are enforced.`
|
||||
);
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
// js/analytics.js
|
||||
import { ANALYTICS_CONFIG } from "./analyticsConfig.js";
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
|
||||
const SCRIPT_ATTR = "data-bitvid-analytics";
|
||||
const SCRIPT_IDENTIFIER = "umami";
|
||||
@@ -30,7 +31,7 @@ function flushPendingCalls() {
|
||||
try {
|
||||
fn.apply(umami, args);
|
||||
} catch (err) {
|
||||
console.warn("[analytics] Failed to call", method, err);
|
||||
userLogger.warn("[analytics] Failed to call", method, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,7 +104,7 @@ function invokeUmami(method, args) {
|
||||
try {
|
||||
umami[method].apply(umami, args);
|
||||
} catch (err) {
|
||||
console.warn("[analytics] Failed to call", method, err);
|
||||
userLogger.warn("[analytics] Failed to call", method, err);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
function toArray(value) {
|
||||
if (!value) {
|
||||
return [];
|
||||
@@ -196,7 +197,7 @@ export function destroyCarousel(state) {
|
||||
try {
|
||||
dispose();
|
||||
} catch (error) {
|
||||
console.warn('Failed to dispose carousel listener', error);
|
||||
userLogger.warn('Failed to dispose carousel listener', error);
|
||||
}
|
||||
});
|
||||
state.cleanup = [];
|
||||
|
||||
+9
-8
@@ -1,6 +1,7 @@
|
||||
import { createCarousel, advanceSlide, destroyCarousel } from './carousel.js';
|
||||
import { mountProgressBar } from './progressBar.js';
|
||||
import { initZapthreadsEmbed as defaultInitZapthreadsEmbed } from './zapthreadsEmbed.js';
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
|
||||
const CAROUSEL_AUTOPLAY_INTERVAL = 8000;
|
||||
|
||||
@@ -499,7 +500,7 @@ function initializeZapthreads({ registerCleanup, isDestroyed, initZapthreadsEmbe
|
||||
try {
|
||||
dispose();
|
||||
} catch (error) {
|
||||
console.error('[blog] zapthreads cleanup failed', error);
|
||||
userLogger.error('[blog] zapthreads cleanup failed', error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -507,12 +508,12 @@ function initializeZapthreads({ registerCleanup, isDestroyed, initZapthreadsEmbe
|
||||
try {
|
||||
dispose();
|
||||
} catch (error) {
|
||||
console.error('[blog] zapthreads cleanup failed', error);
|
||||
userLogger.error('[blog] zapthreads cleanup failed', error);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('[blog] failed to initialise zapthreads embed', error);
|
||||
userLogger.error('[blog] failed to initialise zapthreads embed', error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -522,7 +523,7 @@ function initializeZapthreads({ registerCleanup, isDestroyed, initZapthreadsEmbe
|
||||
try {
|
||||
maybeDispose();
|
||||
} catch (error) {
|
||||
console.error('[blog] zapthreads cleanup failed', error);
|
||||
userLogger.error('[blog] zapthreads cleanup failed', error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -530,12 +531,12 @@ function initializeZapthreads({ registerCleanup, isDestroyed, initZapthreadsEmbe
|
||||
try {
|
||||
maybeDispose();
|
||||
} catch (error) {
|
||||
console.error('[blog] zapthreads cleanup failed', error);
|
||||
userLogger.error('[blog] zapthreads cleanup failed', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[blog] failed to start zapthreads embed', error);
|
||||
userLogger.error('[blog] failed to start zapthreads embed', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -555,7 +556,7 @@ function mountBlogApp({ initZapthreadsEmbed = defaultInitZapthreadsEmbed } = {})
|
||||
try {
|
||||
callback();
|
||||
} catch (error) {
|
||||
console.error('[blog] cleanup callback failed', error);
|
||||
userLogger.error('[blog] cleanup callback failed', error);
|
||||
}
|
||||
return () => {};
|
||||
}
|
||||
@@ -574,7 +575,7 @@ function mountBlogApp({ initZapthreadsEmbed = defaultInitZapthreadsEmbed } = {})
|
||||
try {
|
||||
callback();
|
||||
} catch (error) {
|
||||
console.error('[blog] cleanup callback failed', error);
|
||||
userLogger.error('[blog] cleanup callback failed', error);
|
||||
}
|
||||
});
|
||||
runtime.cleanupCallbacks.clear();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { escapeHTML } from '../utils/domUtils.js';
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
|
||||
/**
|
||||
* Responsibilities mirrored from the legacy DS component that ships inside
|
||||
@@ -492,7 +493,7 @@ export function parseRelayList(relayList = '') {
|
||||
try {
|
||||
relays.push(new URL(trimmed).toString());
|
||||
} catch (error) {
|
||||
console.warn('[zapthreads] ignored invalid relay input', trimmed, error);
|
||||
userLogger.warn('[zapthreads] ignored invalid relay input', trimmed, error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1161,7 +1162,7 @@ export async function initZapthreadsEmbed({
|
||||
try {
|
||||
callback();
|
||||
} catch (error) {
|
||||
console.error('[zapthreads] cleanup failed', error);
|
||||
userLogger.error('[zapthreads] cleanup failed', error);
|
||||
}
|
||||
});
|
||||
disposeCallbacks.clear();
|
||||
@@ -1194,7 +1195,7 @@ export async function initZapthreadsEmbed({
|
||||
try {
|
||||
currentSubscription.close();
|
||||
} catch (error) {
|
||||
console.error('[zapthreads] failed to close subscription', error);
|
||||
userLogger.error('[zapthreads] failed to close subscription', error);
|
||||
}
|
||||
}
|
||||
currentSubscription = null;
|
||||
@@ -1276,7 +1277,7 @@ export async function initZapthreadsEmbed({
|
||||
try {
|
||||
callback();
|
||||
} catch (error) {
|
||||
console.error('[zapthreads] cleanup failed', error);
|
||||
userLogger.error('[zapthreads] cleanup failed', error);
|
||||
}
|
||||
});
|
||||
disposeCallbacks.clear();
|
||||
|
||||
+24
-23
@@ -41,6 +41,7 @@ import {
|
||||
} from "./payments/lnurl.js";
|
||||
import { getPlatformLightningAddress } from "./payments/platformAddress.js";
|
||||
import {
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
ensureWallet,
|
||||
sendPayment as sendWalletPayment
|
||||
} from "./payments/nwcClient.js";
|
||||
@@ -109,7 +110,7 @@ function logZapError(stage, details = {}, error) {
|
||||
? details.retryAttempt
|
||||
: undefined
|
||||
};
|
||||
console.error("[zap] Channel zap failure", summary, error);
|
||||
userLogger.error("[zap] Channel zap failure", summary, error);
|
||||
}
|
||||
let currentChannelProfileEvent = null;
|
||||
|
||||
@@ -1289,7 +1290,7 @@ function buildChannelShareUrl() {
|
||||
url.hash = `#view=channel-profile&npub=${currentChannelNpub}`;
|
||||
return url.toString();
|
||||
} catch (error) {
|
||||
console.warn("Falling back to basic channel share URL:", error);
|
||||
userLogger.warn("Falling back to basic channel share URL:", error);
|
||||
const origin = window.location?.origin || "";
|
||||
const pathname = window.location?.pathname || "";
|
||||
if (!origin && !pathname) {
|
||||
@@ -1361,7 +1362,7 @@ async function updateChannelMenuState() {
|
||||
try {
|
||||
await accessControl.ensureReady();
|
||||
} catch (error) {
|
||||
console.warn("Failed to refresh moderation lists for channel menu:", error);
|
||||
userLogger.warn("Failed to refresh moderation lists for channel menu:", error);
|
||||
}
|
||||
|
||||
const canBlacklist =
|
||||
@@ -1431,7 +1432,7 @@ export async function initChannelProfileView() {
|
||||
const hashParams = new URLSearchParams(window.location.hash.slice(1));
|
||||
const npub = hashParams.get("npub");
|
||||
if (!npub) {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"No npub found in hash (e.g. #view=channel-profile&npub=...)"
|
||||
);
|
||||
return;
|
||||
@@ -1456,7 +1457,7 @@ export async function initChannelProfileView() {
|
||||
throw new Error("Invalid npub decoding result.");
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Error decoding npub:", err);
|
||||
userLogger.error("Error decoding npub:", err);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1469,7 +1470,7 @@ export async function initChannelProfileView() {
|
||||
setupChannelMoreMenu();
|
||||
|
||||
const initialMenuRefresh = updateChannelMenuState().catch((error) => {
|
||||
console.error("Failed to prepare channel menu state:", error);
|
||||
userLogger.error("Failed to prepare channel menu state:", error);
|
||||
});
|
||||
|
||||
let subscriptionsTask = null;
|
||||
@@ -1478,7 +1479,7 @@ export async function initChannelProfileView() {
|
||||
subscriptionsTask = subscriptions
|
||||
.loadSubscriptions(app.pubkey)
|
||||
.catch((error) => {
|
||||
console.error("Failed to load subscriptions for channel view:", error);
|
||||
userLogger.error("Failed to load subscriptions for channel view:", error);
|
||||
})
|
||||
.finally(() => {
|
||||
renderSubscribeButton(hexPub);
|
||||
@@ -1495,14 +1496,14 @@ export async function initChannelProfileView() {
|
||||
const profilePromise = loadUserProfile(hexPub)
|
||||
.then(() => updateChannelMenuState())
|
||||
.catch((error) => {
|
||||
console.error("Failed to load channel profile:", error);
|
||||
userLogger.error("Failed to load channel profile:", error);
|
||||
})
|
||||
.finally(() => {
|
||||
syncChannelShareButtonState();
|
||||
});
|
||||
|
||||
const videosPromise = loadUserVideos(hexPub).catch((error) => {
|
||||
console.error("Failed to load channel videos:", error);
|
||||
userLogger.error("Failed to load channel videos:", error);
|
||||
});
|
||||
|
||||
const pendingTasks = [profilePromise, videosPromise];
|
||||
@@ -1609,7 +1610,7 @@ function renderSubscribeButton(channelHex) {
|
||||
if (toggleBtn) {
|
||||
toggleBtn.addEventListener("click", async () => {
|
||||
if (!app?.pubkey) {
|
||||
console.error("Not logged in => cannot subscribe/unsubscribe.");
|
||||
userLogger.error("Not logged in => cannot subscribe/unsubscribe.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@@ -1621,7 +1622,7 @@ function renderSubscribeButton(channelHex) {
|
||||
// Re-render the button so it toggles state
|
||||
renderSubscribeButton(channelHex);
|
||||
} catch (err) {
|
||||
console.error("Failed to update subscription:", err);
|
||||
userLogger.error("Failed to update subscription:", err);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1905,7 +1906,7 @@ function renderChannelVideosFromList({
|
||||
description: detail.video?.description
|
||||
})
|
||||
).catch((error) => {
|
||||
console.error("Failed to play channel video via event id:", error);
|
||||
userLogger.error("Failed to play channel video via event id:", error);
|
||||
if (typeof app?.playVideoWithFallback === "function") {
|
||||
app.playVideoWithFallback({
|
||||
url: detail.url,
|
||||
@@ -1920,7 +1921,7 @@ function renderChannelVideosFromList({
|
||||
Promise.resolve(
|
||||
app.playVideoWithFallback({ url: detail.url, magnet: detail.magnet })
|
||||
).catch((error) => {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"Failed to start fallback playback for channel video:",
|
||||
error
|
||||
);
|
||||
@@ -2235,7 +2236,7 @@ async function fetchChannelProfileFromRelays(pubkey) {
|
||||
try {
|
||||
await nostrClient.ensurePool();
|
||||
} catch (error) {
|
||||
console.error("Failed to initialize relay pool for channel profile:", error);
|
||||
userLogger.error("Failed to initialize relay pool for channel profile:", error);
|
||||
return { event: null, profile: {} };
|
||||
}
|
||||
|
||||
@@ -2271,7 +2272,7 @@ async function fetchChannelProfileFromRelays(pubkey) {
|
||||
const meta = JSON.parse(newestEvent.content);
|
||||
return { event: newestEvent, profile: meta };
|
||||
} catch (error) {
|
||||
console.warn("Failed to parse channel metadata payload:", error);
|
||||
userLogger.warn("Failed to parse channel metadata payload:", error);
|
||||
return { event: newestEvent, profile: {} };
|
||||
}
|
||||
}
|
||||
@@ -2343,7 +2344,7 @@ async function loadUserProfile(pubkey) {
|
||||
""
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"Failed to persist channel profile metadata to cache:",
|
||||
error
|
||||
);
|
||||
@@ -2359,7 +2360,7 @@ async function loadUserProfile(pubkey) {
|
||||
});
|
||||
} catch (error) {
|
||||
if (loadToken === currentProfileLoadToken) {
|
||||
console.error("Failed to fetch user profile data:", error);
|
||||
userLogger.error("Failed to fetch user profile data:", error);
|
||||
const lnEl = document.getElementById("channelLightning");
|
||||
if (lnEl && !currentChannelLightningAddress) {
|
||||
lnEl.textContent = "No lightning address found.";
|
||||
@@ -2416,7 +2417,7 @@ async function loadUserVideos(pubkey) {
|
||||
}
|
||||
|
||||
const ensureAccessPromise = accessControl.ensureReady().catch((error) => {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"Failed to ensure admin lists were loaded before channel fetch:",
|
||||
error
|
||||
);
|
||||
@@ -2448,7 +2449,7 @@ async function loadUserVideos(pubkey) {
|
||||
events.push(...fallbackEvents);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Relay error (default pool):", error);
|
||||
userLogger.error("Relay error (default pool):", error);
|
||||
}
|
||||
} else {
|
||||
const relayPromises = relayList.map((url) =>
|
||||
@@ -2466,7 +2467,7 @@ async function loadUserVideos(pubkey) {
|
||||
}
|
||||
|
||||
if (result.reason) {
|
||||
console.error(`Relay error (${relayUrl}):`, result.reason);
|
||||
userLogger.error(`Relay error (${relayUrl}):`, result.reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -2478,7 +2479,7 @@ async function loadUserVideos(pubkey) {
|
||||
}
|
||||
|
||||
if (!container) {
|
||||
console.warn("channelVideoList element not found in DOM.");
|
||||
userLogger.warn("channelVideoList element not found in DOM.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2503,7 +2504,7 @@ async function loadUserVideos(pubkey) {
|
||||
<p class="text-critical">Failed to load videos. Please try again.</p>
|
||||
`;
|
||||
}
|
||||
console.error("Error loading user videos:", err);
|
||||
userLogger.error("Error loading user videos:", err);
|
||||
} finally {
|
||||
await ensureAccessPromise;
|
||||
if (loadToken === currentVideoLoadToken && container) {
|
||||
@@ -2528,7 +2529,7 @@ window.addEventListener("bitvid:access-control-updated", () => {
|
||||
}
|
||||
|
||||
loadUserVideos(currentChannelHex).catch((error) => {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"Failed to refresh channel videos after admin update:",
|
||||
error
|
||||
);
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
// js/config.js
|
||||
|
||||
import {
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
IS_DEV_MODE,
|
||||
ADMIN_SUPER_NPUB,
|
||||
ADMIN_DM_IMAGE_URL,
|
||||
@@ -61,7 +62,7 @@ export function getWhitelistMode() {
|
||||
}
|
||||
return raw === "true";
|
||||
} catch (error) {
|
||||
console.warn("Failed to read whitelist mode from storage:", error);
|
||||
userLogger.warn("Failed to read whitelist mode from storage:", error);
|
||||
return DEFAULT_WHITELIST_ENABLED;
|
||||
}
|
||||
}
|
||||
@@ -70,7 +71,7 @@ export function setWhitelistMode(enabled) {
|
||||
try {
|
||||
localStorage.setItem(WHITELIST_MODE_KEY, enabled ? "true" : "false");
|
||||
} catch (error) {
|
||||
console.warn("Failed to persist whitelist mode to storage:", error);
|
||||
userLogger.warn("Failed to persist whitelist mode to storage:", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -1,3 +1,4 @@
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
const NEW_MODE = "new";
|
||||
|
||||
const FALLBACK_CONTEXT = Object.freeze({
|
||||
@@ -87,9 +88,7 @@ export function applyDesignSystemAttributes(root = null) {
|
||||
try {
|
||||
element.setAttribute("data-ds", mode);
|
||||
} catch (error) {
|
||||
if (typeof console !== "undefined" && console && console.warn) {
|
||||
console.warn("[design-system] Failed to set data-ds attribute:", error);
|
||||
}
|
||||
userLogger.warn("[design-system] Failed to set data-ds attribute:", error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
const DEFAULT_CARD_SELECTOR = ".card[data-video-id]";
|
||||
|
||||
function defaultIsCardVisible(entry) {
|
||||
@@ -78,7 +79,7 @@ export function createCardObserver(options = {}) {
|
||||
return prepared;
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("[cardObserver] prepareEntries failed", err);
|
||||
userLogger.warn("[cardObserver] prepareEntries failed", err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +123,7 @@ export function createCardObserver(options = {}) {
|
||||
state: state.customState,
|
||||
}));
|
||||
} catch (err) {
|
||||
console.warn("[cardObserver] isCardVisible failed", err);
|
||||
userLogger.warn("[cardObserver] isCardVisible failed", err);
|
||||
visible = false;
|
||||
}
|
||||
|
||||
@@ -142,7 +143,7 @@ export function createCardObserver(options = {}) {
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn("[cardObserver] onCardVisible failed", err);
|
||||
userLogger.warn("[cardObserver] onCardVisible failed", err);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -170,7 +171,7 @@ export function createCardObserver(options = {}) {
|
||||
context: { container },
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn("[cardObserver] onCardRegister failed", err);
|
||||
userLogger.warn("[cardObserver] onCardRegister failed", err);
|
||||
}
|
||||
}
|
||||
state.observer.observe(card);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// js/feedEngine/engine.js
|
||||
|
||||
import { isPlainObject } from "./utils.js";
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
|
||||
const DEFAULT_FEED_CONFIG = Object.freeze({
|
||||
timeWindow: null,
|
||||
@@ -93,7 +94,7 @@ function createExecutionContext(entry, { config, hooks, runtime, logger }) {
|
||||
try {
|
||||
resolvedLogger(`[feed:${entry.name}]`, ...args);
|
||||
} catch (error) {
|
||||
console.warn(`[feed:${entry.name}] logger threw`, error);
|
||||
userLogger.warn(`[feed:${entry.name}] logger threw`, error);
|
||||
}
|
||||
},
|
||||
addWhy: (detail) => {
|
||||
|
||||
+3
-2
@@ -2,6 +2,7 @@ import { createCardObserver } from "./dom/cardObserver.js";
|
||||
import { infoHashFromMagnet } from "./magnets.js";
|
||||
import { updateVideoCardSourceVisibility } from "./utils/cardSourceVisibility.js";
|
||||
import { TorrentClient, torrentClient } from "./webtorrent.js";
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
|
||||
const badgeUpdateListeners = new Set();
|
||||
|
||||
@@ -17,7 +18,7 @@ function notifyBadgeUpdate(payload) {
|
||||
try {
|
||||
listener(payload);
|
||||
} catch (err) {
|
||||
console.warn("[gridHealth] badge listener failed", err);
|
||||
userLogger.warn("[gridHealth] badge listener failed", err);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -581,7 +582,7 @@ function handleCardVisible({ card, pendingByCard, priority = 0 }) {
|
||||
setBadge(card, "unhealthy", result);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.warn("[gridHealth] probe failed", err);
|
||||
userLogger.warn("[gridHealth] probe failed", err);
|
||||
pendingByCard.delete(card);
|
||||
if (!card.isConnected) {
|
||||
return;
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@ import PQueue from "https://esm.sh/[email protected]";
|
||||
import { trackerPing } from "./trackerPing.js";
|
||||
import { infoHashFromMagnet } from "./magnets.js";
|
||||
import { HEALTH_TTL_MS, CONCURRENCY } from "./trackerConfig.js";
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
|
||||
const queue = new PQueue({ concurrency: CONCURRENCY });
|
||||
const cache = new Map();
|
||||
@@ -72,7 +73,7 @@ export function queueHealthCheck(magnet, onResult) {
|
||||
setHealthCache(infoHash, health);
|
||||
return health;
|
||||
} catch (err) {
|
||||
console.warn("trackerPing failed", err);
|
||||
userLogger.warn("trackerPing failed", err);
|
||||
return getDefaultHealth();
|
||||
}
|
||||
})
|
||||
|
||||
+17
-16
@@ -12,6 +12,7 @@ import {
|
||||
WATCH_HISTORY_BATCH_PAGE_SIZE
|
||||
} from "./config.js";
|
||||
import { getApplication } from "./applicationContext.js";
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
|
||||
export const WATCH_HISTORY_EMPTY_COPY =
|
||||
"Your watch history is empty. Watch some videos to populate this list.";
|
||||
@@ -53,7 +54,7 @@ function resolveElement(selector) {
|
||||
try {
|
||||
return document.querySelector(selector);
|
||||
} catch (error) {
|
||||
console.warn("[historyView] Failed to query selector:", selector, error);
|
||||
userLogger.warn("[historyView] Failed to query selector:", selector, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -264,7 +265,7 @@ async function defaultRemoveHandler({
|
||||
}
|
||||
} catch (error) {
|
||||
if (isDevEnv) {
|
||||
console.warn("[historyView] Failed to update watch history list:", error);
|
||||
userLogger.warn("[historyView] Failed to update watch history list:", error);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
@@ -307,7 +308,7 @@ function writePreference(key, value) {
|
||||
storage.setItem(key, value);
|
||||
} catch (error) {
|
||||
if (isDevEnv) {
|
||||
console.warn("[historyView] Failed to persist preference:", error);
|
||||
userLogger.warn("[historyView] Failed to persist preference:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -732,7 +733,7 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
unsubscribe();
|
||||
} catch (error) {
|
||||
if (isDevEnv) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[historyView] Failed to unsubscribe from watch history event:",
|
||||
error
|
||||
);
|
||||
@@ -1133,7 +1134,7 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
return result.trim();
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[historyView] Failed to resolve actor via getActor:",
|
||||
error
|
||||
);
|
||||
@@ -1177,7 +1178,7 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
watchHistoryService.getLocalMetadata(pointerKeyValue) || null;
|
||||
} catch (error) {
|
||||
if (isDevEnv) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[historyView] Failed to read stored metadata for pointer:",
|
||||
pointerKeyValue,
|
||||
error
|
||||
@@ -1213,7 +1214,7 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
});
|
||||
} catch (error) {
|
||||
if (isDevEnv) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[historyView] Failed to persist metadata for pointer:",
|
||||
pointerKeyValue,
|
||||
error
|
||||
@@ -1227,7 +1228,7 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
watchHistoryService.removeLocalMetadata(pointerKeyValue);
|
||||
} catch (error) {
|
||||
if (isDevEnv) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[historyView] Failed to remove cached metadata for pointer:",
|
||||
pointerKeyValue,
|
||||
error
|
||||
@@ -1268,7 +1269,7 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
} catch (error) {
|
||||
state.isRendering = false;
|
||||
if (isDevEnv) {
|
||||
console.warn("[historyView] Failed to hydrate batch:", error);
|
||||
userLogger.warn("[historyView] Failed to hydrate batch:", error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1441,7 +1442,7 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
watchHistoryService.clearLocalMetadata?.();
|
||||
} catch (error) {
|
||||
if (isDevEnv) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[historyView] Failed to clear stored metadata while resetting progress:",
|
||||
error
|
||||
);
|
||||
@@ -1484,7 +1485,7 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
const app = getAppInstance();
|
||||
app?.showError?.("Failed to publish watch history. Try again later.");
|
||||
if (isDevEnv) {
|
||||
console.warn("[historyView] Republish failed:", error);
|
||||
userLogger.warn("[historyView] Republish failed:", error);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1560,7 +1561,7 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
}
|
||||
} catch (error) {
|
||||
if (isDevEnv) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[historyView] Failed to set metadata preference:",
|
||||
error
|
||||
);
|
||||
@@ -1576,7 +1577,7 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
watchHistoryService.clearLocalMetadata?.();
|
||||
} catch (error) {
|
||||
if (isDevEnv) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[historyView] Failed to clear stored metadata after disabling preference:",
|
||||
error
|
||||
);
|
||||
@@ -1909,7 +1910,7 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
watchHistoryService.removeLocalMetadata?.(pointerKeyValue);
|
||||
} catch (error) {
|
||||
if (isDevEnv) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[historyView] Failed to drop cached metadata for pointer:",
|
||||
pointerKeyValue,
|
||||
error
|
||||
@@ -1948,7 +1949,7 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
app?.showError?.("Failed to remove from history. Reloading list.");
|
||||
}
|
||||
if (isDevEnv) {
|
||||
console.warn("[historyView] Removal failed:", error);
|
||||
userLogger.warn("[historyView] Removal failed:", error);
|
||||
}
|
||||
} finally {
|
||||
if (parentDay instanceof HTMLElement) {
|
||||
@@ -1959,7 +1960,7 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
await this.refresh({ force: true });
|
||||
} catch (error) {
|
||||
if (isDevEnv) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[historyView] Failed to refresh watch history after removal:",
|
||||
error
|
||||
);
|
||||
|
||||
+20
-19
@@ -14,6 +14,7 @@ import {
|
||||
refreshThemeControls,
|
||||
} from "./themeController.js";
|
||||
import {
|
||||
import { devLogger, userLogger } from "./utils/logger.js";
|
||||
prepareStaticModal,
|
||||
openStaticModal,
|
||||
closeStaticModal,
|
||||
@@ -53,7 +54,7 @@ function startApplication() {
|
||||
setApplicationReady(startupPromise);
|
||||
|
||||
startupPromise.catch((error) => {
|
||||
console.error("Application failed to initialize:", error);
|
||||
userLogger.error("Application failed to initialize:", error);
|
||||
});
|
||||
|
||||
return startupPromise;
|
||||
@@ -149,9 +150,9 @@ async function loadModal(url) {
|
||||
applyDesignSystemAttributes(modalContainer);
|
||||
refreshThemeControls(modalContainer);
|
||||
}
|
||||
console.log(url, "loaded");
|
||||
devLogger.log(url, "loaded");
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
userLogger.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,9 +166,9 @@ async function loadSidebar(url, containerId) {
|
||||
applyDesignSystemAttributes(container);
|
||||
refreshThemeControls(container);
|
||||
}
|
||||
console.log(url, "loaded into", containerId);
|
||||
devLogger.log(url, "loaded into", containerId);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
userLogger.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,9 +182,9 @@ async function loadDisclaimer(url, containerId) {
|
||||
applyDesignSystemAttributes(container);
|
||||
refreshThemeControls(container);
|
||||
}
|
||||
console.log(url, "disclaimer loaded into", containerId);
|
||||
devLogger.log(url, "disclaimer loaded into", containerId);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
userLogger.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +198,7 @@ async function bootstrapInterface() {
|
||||
loadModal("components/bug-fix-form.html"),
|
||||
]);
|
||||
|
||||
console.log("Modals loaded.");
|
||||
devLogger.log("Modals loaded.");
|
||||
|
||||
[
|
||||
"loginModal",
|
||||
@@ -211,7 +212,7 @@ async function bootstrapInterface() {
|
||||
});
|
||||
|
||||
await loadSidebar("components/sidebar.html", "sidebarContainer");
|
||||
console.log("Sidebar loaded.");
|
||||
devLogger.log("Sidebar loaded.");
|
||||
|
||||
const sidebar = document.getElementById("sidebar");
|
||||
const collapseToggle = document.getElementById("sidebarCollapseToggle");
|
||||
@@ -219,7 +220,7 @@ async function bootstrapInterface() {
|
||||
sidebar.setAttribute("data-footer-state", "collapsed");
|
||||
}
|
||||
if (!collapseToggle) {
|
||||
console.warn("Sidebar collapse toggle not found; skipping density controls.");
|
||||
userLogger.warn("Sidebar collapse toggle not found; skipping density controls.");
|
||||
}
|
||||
|
||||
const mobileMenuBtn = document.getElementById("mobileMenuBtn");
|
||||
@@ -241,7 +242,7 @@ async function bootstrapInterface() {
|
||||
}
|
||||
return storedValue === "true";
|
||||
} catch (error) {
|
||||
console.warn("Unable to read sidebar collapse state from storage:", error);
|
||||
userLogger.warn("Unable to read sidebar collapse state from storage:", error);
|
||||
return DEFAULT_SIDEBAR_COLLAPSED;
|
||||
}
|
||||
};
|
||||
@@ -253,7 +254,7 @@ async function bootstrapInterface() {
|
||||
collapsed ? "true" : "false",
|
||||
);
|
||||
} catch (error) {
|
||||
console.warn("Unable to persist sidebar collapse state:", error);
|
||||
userLogger.warn("Unable to persist sidebar collapse state:", error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -469,11 +470,11 @@ async function bootstrapInterface() {
|
||||
sidebarModule.setupSidebarNavigation({ closeSidebar });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to set up sidebar navigation:", error);
|
||||
userLogger.error("Failed to set up sidebar navigation:", error);
|
||||
}
|
||||
|
||||
await loadDisclaimer("components/disclaimer.html", "modalContainer");
|
||||
console.log("Disclaimer loaded.");
|
||||
devLogger.log("Disclaimer loaded.");
|
||||
prepareStaticModal({ id: "disclaimerModal" });
|
||||
|
||||
const loginNavBtn = document.getElementById("loginButton");
|
||||
@@ -538,13 +539,13 @@ async function initializeInterface() {
|
||||
try {
|
||||
await bootstrapInterface();
|
||||
} catch (error) {
|
||||
console.error("Failed to bootstrap bitvid interface:", error);
|
||||
userLogger.error("Failed to bootstrap bitvid interface:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function onDomReady() {
|
||||
initializeInterface().catch((error) => {
|
||||
console.error("Unhandled error during bitvid initialization:", error);
|
||||
userLogger.error("Unhandled error during bitvid initialization:", error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -676,12 +677,12 @@ function handleQueryParams() {
|
||||
}
|
||||
|
||||
async function handleHashChange() {
|
||||
console.log("handleHashChange called, current hash =", window.location.hash);
|
||||
devLogger.log("handleHashChange called, current hash =", window.location.hash);
|
||||
|
||||
try {
|
||||
await applicationReadyPromise;
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"Proceeding with hash handling despite application initialization failure:",
|
||||
error
|
||||
);
|
||||
@@ -715,6 +716,6 @@ async function handleHashChange() {
|
||||
await initFn();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to handle hash change:", error);
|
||||
userLogger.error("Failed to handle hash change:", error);
|
||||
}
|
||||
}
|
||||
+299
-483
File diff suppressed because it is too large.
Load diff
+14
-20
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
import { devLogger } from "./utils/logger.js";
|
||||
ADMIN_LIST_NAMESPACE,
|
||||
isDevMode,
|
||||
WATCH_HISTORY_KIND,
|
||||
@@ -46,12 +47,10 @@ function ensureValidUtf8Content(value) {
|
||||
const stringified = JSON.stringify(value);
|
||||
normalized = typeof stringified === "string" ? stringified : "";
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[nostrEventSchemas] Failed to serialize view event content:",
|
||||
error
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[nostrEventSchemas] Failed to serialize view event content:",
|
||||
error
|
||||
);
|
||||
normalized = "";
|
||||
}
|
||||
} else {
|
||||
@@ -66,12 +65,10 @@ function ensureValidUtf8Content(value) {
|
||||
try {
|
||||
cachedUtf8Encoder.encode(normalized);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[nostrEventSchemas] Dropping invalid UTF-8 characters from event content",
|
||||
error
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[nostrEventSchemas] Dropping invalid UTF-8 characters from event content",
|
||||
error
|
||||
);
|
||||
const sanitized = Array.from(normalized)
|
||||
.filter((char) => {
|
||||
const code = char.charCodeAt(0);
|
||||
@@ -82,12 +79,10 @@ function ensureValidUtf8Content(value) {
|
||||
cachedUtf8Encoder.encode(sanitized);
|
||||
normalized = sanitized;
|
||||
} catch (encodeError) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[nostrEventSchemas] Failed to normalize view event content; defaulting to empty string",
|
||||
encodeError
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[nostrEventSchemas] Failed to normalize view event content; defaulting to empty string",
|
||||
encodeError
|
||||
);
|
||||
normalized = "";
|
||||
}
|
||||
}
|
||||
@@ -835,8 +830,7 @@ function resolveAdminNoteType(listKey) {
|
||||
export function buildAdminListEvent(listKey, { pubkey, created_at, hexPubkeys = [] }) {
|
||||
const schema = getNostrEventSchema(resolveAdminNoteType(listKey));
|
||||
if (!schema) {
|
||||
if (isDevMode) {
|
||||
console.warn(`[nostrEventSchemas] Unknown admin list key: ${listKey}`);
|
||||
devLogger.warn(`[nostrEventSchemas] Unknown admin list key: ${listKey`);
|
||||
}
|
||||
return {
|
||||
kind: 30000,
|
||||
|
||||
+5
-6
@@ -1,4 +1,5 @@
|
||||
import { isDevMode } from "./config.js";
|
||||
import { devLogger } from "./utils/logger.js";
|
||||
|
||||
export const RELAY_PUBLISH_TIMEOUT_MS = 10_000;
|
||||
|
||||
@@ -88,12 +89,10 @@ export function publishEventToRelay(pool, url, event, options = {}) {
|
||||
pub.on(eventName, handler);
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
`[nostrPublish] Relay publish handle rejected ${eventName} listener:`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
`[nostrPublish] Relay publish handle rejected ${eventName} listener:`,
|
||||
error,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { devLogger, userLogger } from "./utils/logger.js";
|
||||
const REMOTE_IMPORT_TIMEOUT = 4500;
|
||||
const LOCAL_IMPORT_TIMEOUT = 2500;
|
||||
const NODE_IMPORT_TIMEOUT = 1500;
|
||||
@@ -416,7 +417,7 @@ export function bootstrapNostrTools() {
|
||||
reason: "Failed to resolve any nostr-tools helpers.",
|
||||
attempts,
|
||||
};
|
||||
console.warn("[bitvid] nostr-tools bootstrap failed", failure);
|
||||
userLogger.warn("[bitvid] nostr-tools bootstrap failed", failure);
|
||||
return failure;
|
||||
}
|
||||
|
||||
@@ -446,9 +447,9 @@ export function bootstrapNostrTools() {
|
||||
|
||||
if (resolvedNip04) {
|
||||
canonicalTools.nip04 = resolvedNip04;
|
||||
console.info("[bitvid] Initialized nostr nip04 helpers.");
|
||||
devLogger.info("[bitvid] Initialized nostr nip04 helpers.");
|
||||
} else {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[bitvid] NIP-04 helpers unavailable after bootstrap attempts."
|
||||
);
|
||||
}
|
||||
@@ -507,7 +508,7 @@ export function bootstrapNostrTools() {
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn("[bitvid] Failed to install NostrTools guard.", error);
|
||||
userLogger.warn("[bitvid] Failed to install NostrTools guard.", error);
|
||||
}
|
||||
|
||||
applyActive(existingGlobalTools);
|
||||
|
||||
+4
-3
@@ -1,3 +1,4 @@
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
const DB_NAME = "bitvidSettings";
|
||||
const DB_VERSION = 1;
|
||||
const STORE_NAME = "kv";
|
||||
@@ -183,20 +184,20 @@ function emitToast(message, { variant = "error", error } = {}) {
|
||||
})
|
||||
);
|
||||
} catch (eventError) {
|
||||
console.warn("[nwcSettings] Failed to dispatch toast event", eventError);
|
||||
userLogger.warn("[nwcSettings] Failed to dispatch toast event", eventError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function notifyFailure(message, error) {
|
||||
const text = message || "NWC settings storage error.";
|
||||
console.warn(`[nwcSettings] ${text}`, error);
|
||||
userLogger.warn(`[nwcSettings] ${text}`, error);
|
||||
emitToast(text, { variant: "error", error });
|
||||
}
|
||||
|
||||
function notifyWarning(message, error) {
|
||||
const text = message || "NWC settings storage warning.";
|
||||
console.warn(`[nwcSettings] ${text}`, error);
|
||||
userLogger.warn(`[nwcSettings] ${text}`, error);
|
||||
emitToast(text, { variant: "warning", error });
|
||||
}
|
||||
|
||||
|
||||
+16
-15
@@ -1,6 +1,7 @@
|
||||
// js/payments/nwcClient.js
|
||||
|
||||
import { nostrToolsReady } from "../nostrToolsBootstrap.js";
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
|
||||
const HEX64_REGEX = /^[0-9a-f]{64}$/i;
|
||||
const URI_SCHEMES = [
|
||||
@@ -119,7 +120,7 @@ let cachedNostrTools = __nwcNostrToolsBootstrap.toolkit || null;
|
||||
const nostrToolsInitializationFailure = __nwcNostrToolsBootstrap.failure || null;
|
||||
|
||||
if (!cachedNostrTools && nostrToolsInitializationFailure) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[nwcClient] nostr-tools helpers unavailable after bootstrap.",
|
||||
nostrToolsInitializationFailure
|
||||
);
|
||||
@@ -150,7 +151,7 @@ async function ensureNostrTools() {
|
||||
const result = await nostrToolsReadySource;
|
||||
rememberNostrTools(result);
|
||||
} catch (error) {
|
||||
console.warn("[nwcClient] Failed to resolve nostr-tools helpers.", error);
|
||||
userLogger.warn("[nwcClient] Failed to resolve nostr-tools helpers.", error);
|
||||
}
|
||||
if (!cachedNostrTools) {
|
||||
rememberNostrTools(readToolkitFromScope());
|
||||
@@ -200,15 +201,15 @@ function assertNostrTools(methods = []) {
|
||||
const available = Array.isArray(Object.keys(tools))
|
||||
? Object.keys(tools)
|
||||
: [];
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"[nwcClient] Required NostrTools capability is missing.",
|
||||
{
|
||||
missingMethod: method,
|
||||
availableMethods: available,
|
||||
missingMethod: method,
|
||||
availableMethods: available,
|
||||
}
|
||||
);
|
||||
} catch (loggingError) {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"[nwcClient] Failed to enumerate available NostrTools methods.",
|
||||
loggingError
|
||||
);
|
||||
@@ -454,7 +455,7 @@ function createNip44Encryption(context) {
|
||||
const secretBytes = hexToBytesCompat(context.secretKey);
|
||||
cachedKey = resolved.getConversationKey(secretBytes, context.walletPubkey);
|
||||
} catch (error) {
|
||||
console.warn("[nwcClient] Failed to derive nip44 conversation key", error);
|
||||
userLogger.warn("[nwcClient] Failed to derive nip44 conversation key", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -527,7 +528,7 @@ function settleInfoRequest(result) {
|
||||
try {
|
||||
resolver(result || null);
|
||||
} catch (error) {
|
||||
console.warn("[nwcClient] Failed to resolve wallet info request", error);
|
||||
userLogger.warn("[nwcClient] Failed to resolve wallet info request", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -571,7 +572,7 @@ function requestInfoEvent(context) {
|
||||
try {
|
||||
socket.send(JSON.stringify(["REQ", infoSubscriptionId, filters]));
|
||||
} catch (error) {
|
||||
console.warn("[nwcClient] Failed to request wallet info event", error);
|
||||
userLogger.warn("[nwcClient] Failed to request wallet info event", error);
|
||||
settleInfoRequest(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
@@ -619,7 +620,7 @@ async function ensureEncryption(context) {
|
||||
try {
|
||||
infoEvent = await requestInfoEvent(context);
|
||||
} catch (error) {
|
||||
console.warn("[nwcClient] Failed to load wallet info event", error);
|
||||
userLogger.warn("[nwcClient] Failed to load wallet info event", error);
|
||||
}
|
||||
if (infoEvent) {
|
||||
context.infoEvent = infoEvent;
|
||||
@@ -735,12 +736,12 @@ function isSocketOpen() {
|
||||
}
|
||||
|
||||
function handleSocketError(error) {
|
||||
console.warn("[nwcClient] WebSocket error", error);
|
||||
userLogger.warn("[nwcClient] WebSocket error", error);
|
||||
closeSocket({ keepState: true });
|
||||
}
|
||||
|
||||
function handleSocketClose() {
|
||||
console.warn("[nwcClient] Wallet connection closed.");
|
||||
userLogger.warn("[nwcClient] Wallet connection closed.");
|
||||
closeSocket({ keepState: true });
|
||||
}
|
||||
|
||||
@@ -782,7 +783,7 @@ async function handleSocketMessage(messageEvent) {
|
||||
try {
|
||||
payload = JSON.parse(messageEvent.data);
|
||||
} catch (error) {
|
||||
console.warn("[nwcClient] Failed to parse relay message", error);
|
||||
userLogger.warn("[nwcClient] Failed to parse relay message", error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -815,7 +816,7 @@ async function handleSocketMessage(messageEvent) {
|
||||
finalizePendingRequest(pending);
|
||||
pending.reject(error);
|
||||
} else {
|
||||
console.warn("[nwcClient] Failed to decrypt wallet response", error);
|
||||
userLogger.warn("[nwcClient] Failed to decrypt wallet response", error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -860,7 +861,7 @@ async function handleSocketMessage(messageEvent) {
|
||||
}
|
||||
|
||||
if (type === "NOTICE" && payload.length >= 2) {
|
||||
console.warn("[nwcClient] Relay notice:", payload[1]);
|
||||
userLogger.warn("[nwcClient] Relay notice:", payload[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { PLATFORM_LUD16_OVERRIDE, ADMIN_SUPER_NPUB } from "../config.js";
|
||||
import { nostrClient } from "../nostr.js";
|
||||
import { setProfileCacheEntry } from "../state/cache.js";
|
||||
import { nostrToolsReady } from "../nostrToolsBootstrap.js";
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
|
||||
const HEX64_REGEX = /^[0-9a-f]{64}$/i;
|
||||
const CACHE_TTL_MS = 10 * 60 * 1000;
|
||||
@@ -106,7 +107,7 @@ const nostrToolsInitializationFailure =
|
||||
__platformNostrToolsBootstrap.failure || null;
|
||||
|
||||
if (!cachedNostrTools && nostrToolsInitializationFailure) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[platformAddress] nostr-tools helpers unavailable after bootstrap.",
|
||||
nostrToolsInitializationFailure
|
||||
);
|
||||
@@ -137,7 +138,7 @@ async function ensureNostrTools() {
|
||||
const result = await nostrToolsReadySource;
|
||||
rememberNostrTools(result);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[platformAddress] Failed to resolve nostr-tools helpers.",
|
||||
error
|
||||
);
|
||||
@@ -198,7 +199,7 @@ function decodeAdminPubkey() {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("[platformAddress] Failed to decode ADMIN_SUPER_NPUB", error);
|
||||
userLogger.warn("[platformAddress] Failed to decode ADMIN_SUPER_NPUB", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +234,7 @@ async function fetchAdminMetadata(adminPubkey) {
|
||||
try {
|
||||
pool = await nostrClient.ensurePool();
|
||||
} catch (error) {
|
||||
console.warn("[platformAddress] Failed to initialize Nostr pool", error);
|
||||
userLogger.warn("[platformAddress] Failed to initialize Nostr pool", error);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -245,7 +246,7 @@ async function fetchAdminMetadata(adminPubkey) {
|
||||
? nostrClient.relays
|
||||
: [];
|
||||
if (relayUrls.length === 0) {
|
||||
console.warn("[platformAddress] Nostr client is not ready.");
|
||||
userLogger.warn("[platformAddress] Nostr client is not ready.");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -286,7 +287,7 @@ async function fetchAdminMetadata(adminPubkey) {
|
||||
|
||||
return lightningAddress || null;
|
||||
} catch (error) {
|
||||
console.warn("[platformAddress] Failed to fetch admin metadata", error);
|
||||
userLogger.warn("[platformAddress] Failed to fetch admin metadata", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
import { ensureWallet, sendPayment } from "./nwcClient.js";
|
||||
import { getPlatformLightningAddress } from "./platformAddress.js";
|
||||
import {
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
clampPercent,
|
||||
parsePercentValue,
|
||||
resolvePlatformFeePercent,
|
||||
@@ -124,7 +125,7 @@ let cachedNostrTools = __zapNostrToolsBootstrap.toolkit || null;
|
||||
const nostrToolsInitializationFailure = __zapNostrToolsBootstrap.failure || null;
|
||||
|
||||
if (!cachedNostrTools && nostrToolsInitializationFailure) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[zapSplit] nostr-tools helpers unavailable after bootstrap.",
|
||||
nostrToolsInitializationFailure
|
||||
);
|
||||
@@ -155,7 +156,7 @@ async function ensureNostrTools() {
|
||||
const result = await nostrToolsReadySource;
|
||||
rememberNostrTools(result);
|
||||
} catch (error) {
|
||||
console.warn("[zapSplit] Failed to resolve nostr-tools helpers.", error);
|
||||
userLogger.warn("[zapSplit] Failed to resolve nostr-tools helpers.", error);
|
||||
}
|
||||
if (!cachedNostrTools) {
|
||||
rememberNostrTools(readToolkitFromScope());
|
||||
|
||||
+9
-8
@@ -7,6 +7,7 @@ import {
|
||||
setManagedDomain,
|
||||
} from "./storage/r2-mgmt.js";
|
||||
import { makeR2Client, multipartUpload } from "./storage/r2-s3.js";
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
|
||||
const STORAGE_KEY = "bitvid:quickR2Settings";
|
||||
const STATUS_CLASSNAMES = [
|
||||
@@ -46,7 +47,7 @@ function loadSavedSettings() {
|
||||
}
|
||||
return parsed;
|
||||
} catch (err) {
|
||||
console.warn("Failed to read quick R2 settings:", err);
|
||||
userLogger.warn("Failed to read quick R2 settings:", err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -55,7 +56,7 @@ function persistSettings(settings) {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(settings));
|
||||
} catch (err) {
|
||||
console.warn("Failed to store quick R2 settings:", err);
|
||||
userLogger.warn("Failed to store quick R2 settings:", err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +64,7 @@ function clearSavedSettings() {
|
||||
try {
|
||||
localStorage.removeItem(STORAGE_KEY);
|
||||
} catch (err) {
|
||||
console.warn("Failed to clear quick R2 settings:", err);
|
||||
userLogger.warn("Failed to clear quick R2 settings:", err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +259,7 @@ export function initQuickR2Upload(app) {
|
||||
origins: getCorsOrigins(),
|
||||
});
|
||||
} catch (corsErr) {
|
||||
console.warn("Quick R2 CORS update failed:", corsErr);
|
||||
userLogger.warn("Quick R2 CORS update failed:", corsErr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +293,7 @@ export function initQuickR2Upload(app) {
|
||||
enabled: false,
|
||||
});
|
||||
} catch (disableErr) {
|
||||
console.warn("Quick R2 managed domain disable failed:", disableErr);
|
||||
userLogger.warn("Quick R2 managed domain disable failed:", disableErr);
|
||||
}
|
||||
} else {
|
||||
setStatus(
|
||||
@@ -302,7 +303,7 @@ export function initQuickR2Upload(app) {
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("Quick R2 custom domain error:", err);
|
||||
userLogger.warn("Quick R2 custom domain error:", err);
|
||||
setStatus(
|
||||
elements.status,
|
||||
err?.message
|
||||
@@ -332,7 +333,7 @@ export function initQuickR2Upload(app) {
|
||||
usedManagedFallback = true;
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("Quick R2 managed domain enable failed:", err);
|
||||
userLogger.warn("Quick R2 managed domain enable failed:", err);
|
||||
setStatus(
|
||||
elements.status,
|
||||
err?.message
|
||||
@@ -393,7 +394,7 @@ export function initQuickR2Upload(app) {
|
||||
elements.form.requestSubmit();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Quick R2 upload failed:", err);
|
||||
userLogger.error("Quick R2 upload failed:", err);
|
||||
setStatus(
|
||||
elements.status,
|
||||
err?.message ? `Upload failed: ${err.message}` : "Upload failed.",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
const DB_NAME = "bitvidSettings";
|
||||
const DB_VERSION = 1;
|
||||
const STORE_NAME = "kv";
|
||||
@@ -104,7 +105,7 @@ export async function loadR2Settings() {
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("Failed to open IndexedDB for settings, falling back:", err);
|
||||
userLogger.warn("Failed to open IndexedDB for settings, falling back:", err);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -115,7 +116,7 @@ export async function loadR2Settings() {
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("Failed to read fallback settings:", err);
|
||||
userLogger.warn("Failed to read fallback settings:", err);
|
||||
}
|
||||
|
||||
return normalizeSettings(null);
|
||||
@@ -128,7 +129,7 @@ export async function saveR2Settings(settings) {
|
||||
try {
|
||||
db = await openSettingsDb();
|
||||
} catch (err) {
|
||||
console.warn("Unable to open IndexedDB, continuing with fallback:", err);
|
||||
userLogger.warn("Unable to open IndexedDB, continuing with fallback:", err);
|
||||
}
|
||||
|
||||
if (db) {
|
||||
@@ -165,7 +166,7 @@ export async function clearR2Settings() {
|
||||
cleared = true;
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("Failed to clear IndexedDB settings:", err);
|
||||
userLogger.warn("Failed to clear IndexedDB settings:", err);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -174,7 +175,7 @@ export async function clearR2Settings() {
|
||||
cleared = true;
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("Failed to clear fallback settings:", err);
|
||||
userLogger.warn("Failed to clear fallback settings:", err);
|
||||
}
|
||||
|
||||
return cleared;
|
||||
|
||||
+12
-19
@@ -2,6 +2,7 @@ import { isDevMode } from "./config.js";
|
||||
import { DEFAULT_RELAY_URLS, nostrClient } from "./nostr.js";
|
||||
import { buildRelayListEvent } from "./nostrEventSchemas.js";
|
||||
import {
|
||||
import { devLogger, userLogger } from "./utils/logger.js";
|
||||
publishEventToRelays,
|
||||
assertAnyRelayAccepted,
|
||||
} from "./nostrPublish.js";
|
||||
@@ -537,17 +538,13 @@ class RelayPreferencesManager {
|
||||
} else {
|
||||
const reason = outcome.reason;
|
||||
if (reason?.code === "timeout") {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
`[relayManager] Relay ${reason.relay} timed out while loading relay list (${reason.timeoutMs}ms)`
|
||||
);
|
||||
}
|
||||
} else if (isDevMode) {
|
||||
console.warn(
|
||||
`[relayManager] Relay ${reason?.relay || "unknown"} failed while loading relay list:`,
|
||||
reason
|
||||
devLogger.warn(
|
||||
`[relayManager] Relay ${reason.relay} timed out while loading relay list (${reason.timeoutMs}ms)`
|
||||
);
|
||||
}
|
||||
} else devLogger.warn(
|
||||
`[relayManager] Relay ${reason?.relay || "unknown"} failed while loading relay list:`,
|
||||
reason
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -558,9 +555,7 @@ class RelayPreferencesManager {
|
||||
applyEvents(aggregated, { skipIfEmpty: true });
|
||||
})
|
||||
.catch((error) => {
|
||||
if (isDevMode) {
|
||||
console.warn("[relayManager] Background relay refresh failed", error);
|
||||
}
|
||||
devLogger.warn("[relayManager] Background relay refresh failed", error);
|
||||
});
|
||||
|
||||
let fastResult = null;
|
||||
@@ -571,14 +566,12 @@ class RelayPreferencesManager {
|
||||
if (error instanceof AggregateError) {
|
||||
error.errors?.forEach((err) => {
|
||||
if (err?.code === "timeout" && isDevMode) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
`[relayManager] Relay ${err.relay} timed out while loading relay list (${err.timeoutMs}ms)`
|
||||
);
|
||||
}
|
||||
});
|
||||
} else if (isDevMode) {
|
||||
console.warn("[relayManager] Fast relay fetch failed", error);
|
||||
}
|
||||
} else devLogger.warn("[relayManager] Fast relay fetch failed", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -657,7 +650,7 @@ class RelayPreferencesManager {
|
||||
if (publishError?.relayFailures?.length) {
|
||||
publishError.relayFailures.forEach(
|
||||
({ url, error: relayError, reason }) => {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
`[RelayPreferencesManager] Relay ${url} rejected relay list: ${reason}`,
|
||||
relayError || reason
|
||||
);
|
||||
@@ -675,7 +668,7 @@ class RelayPreferencesManager {
|
||||
: relayError
|
||||
? String(relayError)
|
||||
: "publish failed";
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
`[RelayPreferencesManager] Relay ${url} did not acknowledge relay list: ${reason}`,
|
||||
relayError
|
||||
);
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
getCurrentUserNpub,
|
||||
} from "../state/appState.js";
|
||||
import {
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
getSavedProfiles,
|
||||
getActiveProfilePubkey,
|
||||
setActiveProfilePubkey,
|
||||
@@ -94,7 +95,7 @@ export default class AuthService {
|
||||
try {
|
||||
this.logger(message, error);
|
||||
} catch (logError) {
|
||||
console.warn("[AuthService] logger threw", logError);
|
||||
userLogger.warn("[AuthService] logger threw", logError);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -103,7 +104,7 @@ export default class AuthService {
|
||||
try {
|
||||
this.logger(...args);
|
||||
} catch (error) {
|
||||
console.warn("[AuthService] logger threw", error);
|
||||
userLogger.warn("[AuthService] logger threw", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { isDevMode } from "../config.js";
|
||||
import { devLogger } from "../utils/logger.js";
|
||||
|
||||
const DEFAULT_MAX_DISCUSSION_COUNT_VIDEOS = 24;
|
||||
const COUNT_UNSUPPORTED_TITLE = "Relay does not support NIP-45 COUNT queries.";
|
||||
@@ -14,10 +14,10 @@ function toPositiveInteger(value, fallback) {
|
||||
export default class DiscussionCountService {
|
||||
constructor({
|
||||
maxVideos = DEFAULT_MAX_DISCUSSION_COUNT_VIDEOS,
|
||||
logger = typeof console !== "undefined" ? console : null,
|
||||
logger = devLogger,
|
||||
} = {}) {
|
||||
this.maxVideos = toPositiveInteger(maxVideos, DEFAULT_MAX_DISCUSSION_COUNT_VIDEOS);
|
||||
this.logger = logger;
|
||||
this.logger = logger && typeof logger.warn === "function" ? logger : devLogger;
|
||||
this.videoDiscussionCountCache = new Map();
|
||||
this.inFlightDiscussionCounts = new Map();
|
||||
}
|
||||
@@ -104,7 +104,7 @@ export default class DiscussionCountService {
|
||||
return result;
|
||||
})
|
||||
.catch((error) => {
|
||||
if (isDevMode && this.logger?.warn) {
|
||||
if (this.logger?.warn) {
|
||||
this.logger.warn(
|
||||
`[counts] Failed to fetch discussion count for ${video.id}:`,
|
||||
error
|
||||
|
||||
+12
-11
@@ -5,6 +5,7 @@ import {
|
||||
import { accessControl } from "../accessControl.js";
|
||||
import { ALLOW_NSFW_CONTENT } from "../config.js";
|
||||
import {
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
getVideosMap as getStoredVideosMap,
|
||||
setVideosMap as setStoredVideosMap,
|
||||
getVideoSubscription as getStoredVideoSubscription,
|
||||
@@ -53,7 +54,7 @@ class SimpleEventEmitter {
|
||||
try {
|
||||
this.logger(`nostrService listener for "${eventName}" threw`, error);
|
||||
} catch (logError) {
|
||||
console.warn("[nostrService] listener logger threw", logError);
|
||||
userLogger.warn("[nostrService] listener logger threw", logError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,7 +109,7 @@ export class NostrService {
|
||||
try {
|
||||
this.logger(message, error);
|
||||
} catch (logError) {
|
||||
console.warn("[nostrService] logger threw", logError);
|
||||
userLogger.warn("[nostrService] logger threw", logError);
|
||||
}
|
||||
});
|
||||
this.videosMap = null;
|
||||
@@ -118,7 +119,7 @@ export class NostrService {
|
||||
try {
|
||||
this.logger(...args);
|
||||
} catch (error) {
|
||||
console.warn("[nostrService] logger threw", error);
|
||||
userLogger.warn("[nostrService] logger threw", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +165,7 @@ export class NostrService {
|
||||
try {
|
||||
current.unsub();
|
||||
} catch (error) {
|
||||
console.warn("[nostrService] Failed to unsubscribe from video feed:", error);
|
||||
userLogger.warn("[nostrService] Failed to unsubscribe from video feed:", error);
|
||||
}
|
||||
}
|
||||
this.setVideoSubscription(null);
|
||||
@@ -209,7 +210,7 @@ export class NostrService {
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("[nostrService] isAuthorBlocked handler threw", error);
|
||||
userLogger.warn("[nostrService] isAuthorBlocked handler threw", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +224,7 @@ export class NostrService {
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("[nostrService] access control check failed", error);
|
||||
userLogger.warn("[nostrService] access control check failed", error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -254,7 +255,7 @@ export class NostrService {
|
||||
try {
|
||||
await this.accessControl.ensureReady();
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[nostrService] Failed to ensure access control lists are ready:",
|
||||
error
|
||||
);
|
||||
@@ -288,7 +289,7 @@ export class NostrService {
|
||||
try {
|
||||
onVideos(filtered, { reason });
|
||||
} catch (error) {
|
||||
console.warn("[nostrService] onVideos handler threw", error);
|
||||
userLogger.warn("[nostrService] onVideos handler threw", error);
|
||||
}
|
||||
}
|
||||
this.emit("videos:updated", { videos: filtered, reason });
|
||||
@@ -318,7 +319,7 @@ export class NostrService {
|
||||
this.emit("videos:fetched", { videos: filtered });
|
||||
return filtered;
|
||||
} catch (error) {
|
||||
console.error("[nostrService] Failed to fetch videos:", error);
|
||||
userLogger.error("[nostrService] Failed to fetch videos:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -362,11 +363,11 @@ export class NostrService {
|
||||
collected.set(video.id, video);
|
||||
this.nostrClient.allEvents.set(video.id, video);
|
||||
} catch (error) {
|
||||
console.warn("[nostrService] Failed to convert older event", error);
|
||||
userLogger.warn("[nostrService] Failed to convert older event", error);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[nostrService] Failed to load older videos:", error);
|
||||
userLogger.error("[nostrService] Failed to load older videos:", error);
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
createDefaultNwcSettings,
|
||||
} from "../nwcSettings.js";
|
||||
import { MAX_WALLET_DEFAULT_ZAP } from "../config.js";
|
||||
import { devLogger, userLogger } from "../utils/logger.js";
|
||||
|
||||
const NWC_URI_SCHEME = "nostr+walletconnect://";
|
||||
|
||||
@@ -17,7 +18,7 @@ export default class NwcSettingsService {
|
||||
normalizeHexPubkey,
|
||||
getActivePubkey,
|
||||
payments = null,
|
||||
logger = console,
|
||||
logger = { dev: devLogger, user: userLogger },
|
||||
notifyError,
|
||||
maxWalletDefaultZap = MAX_WALLET_DEFAULT_ZAP,
|
||||
loadSettings = loadNwcSettings,
|
||||
@@ -32,7 +33,9 @@ export default class NwcSettingsService {
|
||||
? getActivePubkey
|
||||
: () => null;
|
||||
this.payments = payments || null;
|
||||
this.logger = logger || console;
|
||||
const devChannel = logger?.dev && typeof logger.dev.warn === "function" ? logger.dev : devLogger;
|
||||
const userChannel = logger?.user && typeof logger.user.warn === "function" ? logger.user : userLogger;
|
||||
this.logger = { dev: devChannel, user: userChannel };
|
||||
this.notifyError = isFunction(notifyError) ? notifyError : null;
|
||||
this.maxWalletDefaultZap =
|
||||
Number.isFinite(maxWalletDefaultZap) && maxWalletDefaultZap > 0
|
||||
@@ -78,8 +81,8 @@ export default class NwcSettingsService {
|
||||
try {
|
||||
return this.normalizeHexPubkey(pubkey);
|
||||
} catch (error) {
|
||||
if (this.logger && isFunction(this.logger.warn)) {
|
||||
this.logger.warn("[nwcSettings] Failed to normalize pubkey:", error);
|
||||
if (isFunction(this.logger.user?.warn)) {
|
||||
this.logger.user.warn("[nwcSettings] Failed to normalize pubkey:", error);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -100,8 +103,8 @@ export default class NwcSettingsService {
|
||||
this.cache.set(normalized, record);
|
||||
return this.cloneSettings(record);
|
||||
} catch (error) {
|
||||
if (this.logger && isFunction(this.logger.warn)) {
|
||||
this.logger.warn(
|
||||
if (isFunction(this.logger.user?.warn)) {
|
||||
this.logger.user.warn(
|
||||
`[nwcSettings] Failed to load settings for ${normalized}:`,
|
||||
error,
|
||||
);
|
||||
@@ -160,8 +163,8 @@ export default class NwcSettingsService {
|
||||
async updateActiveNwcSettings(partial = {}) {
|
||||
const normalized = this.getNormalizedPubkey(this.getActivePubkey());
|
||||
if (!normalized) {
|
||||
if (this.logger && isFunction(this.logger.warn)) {
|
||||
this.logger.warn(
|
||||
if (isFunction(this.logger.user?.warn)) {
|
||||
this.logger.user.warn(
|
||||
"[nwcSettings] Cannot update settings without an active pubkey.",
|
||||
);
|
||||
}
|
||||
@@ -177,8 +180,8 @@ export default class NwcSettingsService {
|
||||
this.cache.set(normalized, record);
|
||||
return this.cloneSettings(record);
|
||||
} catch (error) {
|
||||
if (this.logger && isFunction(this.logger.warn)) {
|
||||
this.logger.warn(
|
||||
if (isFunction(this.logger.user?.warn)) {
|
||||
this.logger.user.warn(
|
||||
`[nwcSettings] Failed to save settings for ${normalized}:`,
|
||||
error,
|
||||
);
|
||||
@@ -239,8 +242,8 @@ export default class NwcSettingsService {
|
||||
return this.payments.ensureWallet({ settings: merged });
|
||||
}
|
||||
|
||||
if (this.logger && isFunction(this.logger.warn)) {
|
||||
this.logger.warn(
|
||||
if (isFunction(this.logger.dev?.warn)) {
|
||||
this.logger.dev.warn(
|
||||
"[wallet] Falling back to stub ensureWallet implementation. Returning settings without performing a connection test.",
|
||||
);
|
||||
}
|
||||
@@ -256,8 +259,8 @@ export default class NwcSettingsService {
|
||||
try {
|
||||
await this.clearSettings(normalized);
|
||||
} catch (error) {
|
||||
if (this.logger && isFunction(this.logger.warn)) {
|
||||
this.logger.warn(
|
||||
if (isFunction(this.logger.user?.warn)) {
|
||||
this.logger.user.warn(
|
||||
`[nwcSettings] Failed to clear settings for ${normalized}:`,
|
||||
error,
|
||||
);
|
||||
@@ -268,8 +271,8 @@ export default class NwcSettingsService {
|
||||
try {
|
||||
await this.saveSettings(normalized, this.createDefaultNwcSettings());
|
||||
} catch (persistError) {
|
||||
if (this.logger && isFunction(this.logger.warn)) {
|
||||
this.logger.warn(
|
||||
if (isFunction(this.logger.user?.warn)) {
|
||||
this.logger.user.warn(
|
||||
`[nwcSettings] Failed to overwrite settings for ${normalized}:`,
|
||||
persistError,
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
// js/services/playbackService.js
|
||||
|
||||
class SimpleEventEmitter {
|
||||
@@ -73,7 +74,7 @@ export class PlaybackService {
|
||||
try {
|
||||
this.logger(...args);
|
||||
} catch (err) {
|
||||
console.warn("[PlaybackService] logger threw", err);
|
||||
userLogger.warn("[PlaybackService] logger threw", err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-15
@@ -21,6 +21,7 @@ import {
|
||||
ensureBucketCors,
|
||||
} from "../storage/r2-s3.js";
|
||||
import { truncateMiddle } from "../utils/formatters.js";
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
|
||||
const STATUS_VARIANTS = new Set(["info", "success", "error", "warning"]);
|
||||
|
||||
@@ -69,7 +70,7 @@ class R2Service {
|
||||
try {
|
||||
handler(detail);
|
||||
} catch (err) {
|
||||
console.error("[r2Service] Listener error for", event, err);
|
||||
userLogger.error("[r2Service] Listener error for", event, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,7 +226,7 @@ class R2Service {
|
||||
this.populateCloudflareSettingsInputs(settings);
|
||||
return settings;
|
||||
} catch (err) {
|
||||
console.error("Failed to load Cloudflare settings:", err);
|
||||
userLogger.error("Failed to load Cloudflare settings:", err);
|
||||
this.setSettings(createDefaultSettings());
|
||||
this.populateCloudflareSettingsInputs(this.getSettings());
|
||||
this.setCloudflareSettingsStatus(
|
||||
@@ -285,7 +286,7 @@ class R2Service {
|
||||
}
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error("Failed to save Cloudflare settings:", err);
|
||||
userLogger.error("Failed to save Cloudflare settings:", err);
|
||||
if (!quiet) {
|
||||
this.setCloudflareSettingsStatus(
|
||||
"Failed to save settings. Check console for details.",
|
||||
@@ -310,7 +311,7 @@ class R2Service {
|
||||
this.setCloudflareSettingsStatus("Settings cleared.", "success");
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error("Failed to clear Cloudflare settings:", err);
|
||||
userLogger.error("Failed to clear Cloudflare settings:", err);
|
||||
this.setCloudflareSettingsStatus("Failed to clear settings.", "error");
|
||||
return false;
|
||||
}
|
||||
@@ -338,7 +339,7 @@ class R2Service {
|
||||
try {
|
||||
return deriveShortSubdomain(npub);
|
||||
} catch (err) {
|
||||
console.warn("Failed to derive short subdomain, falling back:", err);
|
||||
userLogger.warn("Failed to derive short subdomain, falling back:", err);
|
||||
}
|
||||
|
||||
const base = String(npub || "user")
|
||||
@@ -382,7 +383,7 @@ class R2Service {
|
||||
origins: corsOrigins,
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn("Failed to refresh bucket configuration:", err);
|
||||
userLogger.warn("Failed to refresh bucket configuration:", err);
|
||||
}
|
||||
} else if (accessKeyId && secretAccessKey && corsOrigins.length > 0) {
|
||||
try {
|
||||
@@ -397,7 +398,7 @@ class R2Service {
|
||||
origins: corsOrigins,
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn("Failed to refresh bucket CORS via access keys:", err);
|
||||
userLogger.warn("Failed to refresh bucket CORS via access keys:", err);
|
||||
}
|
||||
}
|
||||
return {
|
||||
@@ -444,7 +445,7 @@ class R2Service {
|
||||
origins: corsOrigins,
|
||||
});
|
||||
} catch (corsErr) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"Failed to ensure R2 CORS rules via access keys. Configure the bucket's CORS policy manually if uploads continue to fail.",
|
||||
corsErr
|
||||
);
|
||||
@@ -485,7 +486,7 @@ class R2Service {
|
||||
origins: corsOrigins,
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn("Failed to apply R2 CORS rules:", err);
|
||||
userLogger.warn("Failed to apply R2 CORS rules:", err);
|
||||
}
|
||||
|
||||
let publicBaseUrl = entry?.publicBaseUrl || "";
|
||||
@@ -517,7 +518,7 @@ class R2Service {
|
||||
enabled: false,
|
||||
});
|
||||
} catch (disableErr) {
|
||||
console.warn("Failed to disable managed domain:", disableErr);
|
||||
userLogger.warn("Failed to disable managed domain:", disableErr);
|
||||
}
|
||||
} else {
|
||||
usedManagedFallback = true;
|
||||
@@ -535,10 +536,10 @@ class R2Service {
|
||||
enabled: false,
|
||||
});
|
||||
} catch (disableErr) {
|
||||
console.warn("Failed to disable managed domain:", disableErr);
|
||||
userLogger.warn("Failed to disable managed domain:", disableErr);
|
||||
}
|
||||
} else {
|
||||
console.warn("Failed to attach custom domain, falling back:", err);
|
||||
userLogger.warn("Failed to attach custom domain, falling back:", err);
|
||||
usedManagedFallback = true;
|
||||
customDomainStatus = "error";
|
||||
}
|
||||
@@ -699,7 +700,7 @@ class R2Service {
|
||||
try {
|
||||
bucketResult = await this.ensureBucketConfigForNpub(npub);
|
||||
} catch (err) {
|
||||
console.error("Failed to prepare R2 bucket:", err);
|
||||
userLogger.error("Failed to prepare R2 bucket:", err);
|
||||
this.setCloudflareUploadStatus(
|
||||
err?.message ? `Bucket setup failed: ${err.message}` : "Bucket setup failed.",
|
||||
"error"
|
||||
@@ -760,7 +761,7 @@ class R2Service {
|
||||
let publishOutcome = true;
|
||||
|
||||
if (typeof publishVideoNote !== "function") {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"publishVideoNote handler missing; skipping publish step."
|
||||
);
|
||||
publishOutcome = false;
|
||||
@@ -805,7 +806,7 @@ class R2Service {
|
||||
|
||||
return publishOutcome;
|
||||
} catch (err) {
|
||||
console.error("Cloudflare upload failed:", err);
|
||||
userLogger.error("Cloudflare upload failed:", err);
|
||||
this.setCloudflareUploadStatus(
|
||||
err?.message ? `Upload failed: ${err.message}` : "Upload failed.",
|
||||
"error"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { isDevMode } from "../config.js";
|
||||
import { pointerArrayToKey } from "../utils/pointer.js";
|
||||
import {
|
||||
import { devLogger, userLogger } from "../utils/logger.js";
|
||||
ingestLocalViewEvent as defaultIngestLocalViewEvent,
|
||||
} from "../viewCounter.js";
|
||||
|
||||
@@ -108,12 +109,10 @@ export default class WatchHistoryTelemetry {
|
||||
try {
|
||||
this.watchHistoryService?.clearLocalMetadata?.();
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryTelemetry] Failed to clear cached metadata after toggle off:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryTelemetry] Failed to clear cached metadata after toggle off:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -122,12 +121,10 @@ export default class WatchHistoryTelemetry {
|
||||
this.watchHistoryPreferenceUnsubscribe = unsubscribe;
|
||||
}
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryTelemetry] Failed to subscribe to metadata preference changes:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryTelemetry] Failed to subscribe to metadata preference changes:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,12 +150,10 @@ export default class WatchHistoryTelemetry {
|
||||
enabled = this.watchHistoryService.shouldStoreMetadata() !== false;
|
||||
}
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryTelemetry] Failed to read metadata settings:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryTelemetry] Failed to read metadata settings:",
|
||||
error,
|
||||
);
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
@@ -168,12 +163,10 @@ export default class WatchHistoryTelemetry {
|
||||
try {
|
||||
this.watchHistoryService?.clearLocalMetadata?.();
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryTelemetry] Failed to purge metadata cache while preference disabled:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryTelemetry] Failed to purge metadata cache while preference disabled:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,13 +198,11 @@ export default class WatchHistoryTelemetry {
|
||||
try {
|
||||
this.watchHistoryService.setLocalMetadata(pointerInfo.key, metadata);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryTelemetry] Failed to persist local metadata for pointer:",
|
||||
pointerInfo.key,
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryTelemetry] Failed to persist local metadata for pointer:",
|
||||
pointerInfo.key,
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,13 +218,11 @@ export default class WatchHistoryTelemetry {
|
||||
try {
|
||||
this.watchHistoryService.removeLocalMetadata(pointerKey);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryTelemetry] Failed to remove cached metadata for pointer:",
|
||||
pointerKey,
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryTelemetry] Failed to remove cached metadata for pointer:",
|
||||
pointerKey,
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,12 +266,10 @@ export default class WatchHistoryTelemetry {
|
||||
try {
|
||||
state.videoEl.removeEventListener(eventName, handler);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
`[watchHistoryTelemetry] Failed to detach ${eventName} listener:`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
`[watchHistoryTelemetry] Failed to detach ${eventName} listener:`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -423,12 +410,10 @@ export default class WatchHistoryTelemetry {
|
||||
viewResult = { ok: false, error: "view-logging-unavailable" };
|
||||
}
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryTelemetry] Exception while recording video view:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryTelemetry] Exception while recording video view:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
const viewOk = !!viewResult?.ok;
|
||||
@@ -451,27 +436,23 @@ export default class WatchHistoryTelemetry {
|
||||
pointer: thresholdPointer,
|
||||
});
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryTelemetry] Failed to ingest local view event:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryTelemetry] Failed to ingest local view event:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (isDevMode && viewResult) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[watchHistoryTelemetry] View event rejected by relays:",
|
||||
viewResult,
|
||||
);
|
||||
}
|
||||
})().catch((error) => {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryTelemetry] Unexpected error while recording video view:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryTelemetry] Unexpected error while recording video view:",
|
||||
error,
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -581,7 +562,7 @@ export default class WatchHistoryTelemetry {
|
||||
try {
|
||||
this.watchHistoryPreferenceUnsubscribe();
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[watchHistoryTelemetry] Failed to unsubscribe watch history preference:",
|
||||
error,
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
const state = {
|
||||
pubkey: null,
|
||||
currentUserNpub: null,
|
||||
@@ -29,7 +30,7 @@ function notifyKey(key, value, previousValue) {
|
||||
try {
|
||||
callback(value, previousValue, createSnapshot());
|
||||
} catch (error) {
|
||||
console.warn(`[appState] subscriber for key "${key}" threw:`, error);
|
||||
userLogger.warn(`[appState] subscriber for key "${key}" threw:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,7 +41,7 @@ function notifyKey(key, value, previousValue) {
|
||||
try {
|
||||
callback(snapshot, { key, value, previousValue });
|
||||
} catch (error) {
|
||||
console.warn("[appState] global subscriber threw:", error);
|
||||
userLogger.warn("[appState] global subscriber threw:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,7 +159,7 @@ function notifyModal(name, value, previousValue) {
|
||||
try {
|
||||
callback(value, previousValue, createSnapshot());
|
||||
} catch (error) {
|
||||
console.warn(`[appState] modal subscriber for "${name}" threw:`, error);
|
||||
userLogger.warn(`[appState] modal subscriber for "${name}" threw:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-8
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
readUrlHealthFromStorage,
|
||||
removeUrlHealthFromStorage,
|
||||
writeUrlHealthToStorage,
|
||||
@@ -187,7 +188,7 @@ export function readSavedProfilesPayloadFromStorage() {
|
||||
}
|
||||
return parsed;
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[cache.readSavedProfilesPayloadFromStorage] Failed to parse payload:",
|
||||
error
|
||||
);
|
||||
@@ -210,12 +211,12 @@ function writeSavedProfilesPayloadToStorage(payload) {
|
||||
error.code === 22 ||
|
||||
error.code === 1014);
|
||||
if (isQuotaError) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[cache.writeSavedProfilesPayloadToStorage] Storage quota exceeded; keeping in-memory copy only.",
|
||||
error
|
||||
);
|
||||
} else {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[cache.writeSavedProfilesPayloadToStorage] Failed to persist saved profiles:",
|
||||
error
|
||||
);
|
||||
@@ -232,7 +233,7 @@ export function persistSavedProfiles({ persistActive = true } = {}) {
|
||||
try {
|
||||
localStorage.removeItem(SAVED_PROFILES_STORAGE_KEY);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[cache.persistSavedProfiles] Failed to remove empty payload:",
|
||||
error
|
||||
);
|
||||
@@ -349,7 +350,7 @@ export function loadSavedProfilesFromStorage() {
|
||||
needsRewrite = true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("[cache.loadSavedProfilesFromStorage] Failed to parse payload:", error);
|
||||
userLogger.warn("[cache.loadSavedProfilesFromStorage] Failed to parse payload:", error);
|
||||
needsRewrite = true;
|
||||
}
|
||||
|
||||
@@ -493,7 +494,7 @@ export function loadProfileCacheFromStorage() {
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("[cache.loadProfileCacheFromStorage] Failed to parse payload:", error);
|
||||
userLogger.warn("[cache.loadProfileCacheFromStorage] Failed to parse payload:", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -532,7 +533,7 @@ export function persistProfileCacheToStorage() {
|
||||
try {
|
||||
localStorage.removeItem(PROFILE_CACHE_STORAGE_KEY);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[cache.persistProfileCacheToStorage] Failed to clear storage:",
|
||||
error
|
||||
);
|
||||
@@ -543,7 +544,7 @@ export function persistProfileCacheToStorage() {
|
||||
try {
|
||||
localStorage.setItem(PROFILE_CACHE_STORAGE_KEY, JSON.stringify(payload));
|
||||
} catch (error) {
|
||||
console.warn("[cache.persistProfileCacheToStorage] Failed to persist cache:", error);
|
||||
userLogger.warn("[cache.persistProfileCacheToStorage] Failed to persist cache:", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+24
-27
@@ -15,6 +15,7 @@ import {
|
||||
import { getApplication } from "./applicationContext.js";
|
||||
import { VideoListView } from "./ui/views/VideoListView.js";
|
||||
import { ALLOW_NSFW_CONTENT } from "./config.js";
|
||||
import { devLogger, userLogger } from "./utils/logger.js";
|
||||
|
||||
const getApp = () => getApplication();
|
||||
|
||||
@@ -40,7 +41,7 @@ class SubscriptionsManager {
|
||||
*/
|
||||
async loadSubscriptions(userPubkey) {
|
||||
if (!userPubkey) {
|
||||
console.warn("[SubscriptionsManager] No pubkey => cannot load subs.");
|
||||
userLogger.warn("[SubscriptionsManager] No pubkey => cannot load subs.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@@ -59,7 +60,7 @@ class SubscriptionsManager {
|
||||
events.push(...result);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`[SubscriptionsManager] Relay error at ${url}`, err);
|
||||
userLogger.error(`[SubscriptionsManager] Relay error at ${url}`, err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +83,7 @@ class SubscriptionsManager {
|
||||
newest.content
|
||||
);
|
||||
} catch (errDecrypt) {
|
||||
console.error("[SubscriptionsManager] Decryption failed:", errDecrypt);
|
||||
userLogger.error("[SubscriptionsManager] Decryption failed:", errDecrypt);
|
||||
this.subscribedPubkeys.clear();
|
||||
this.subsEventId = null;
|
||||
this.loaded = true;
|
||||
@@ -97,7 +98,7 @@ class SubscriptionsManager {
|
||||
|
||||
this.loaded = true;
|
||||
} catch (err) {
|
||||
console.error("[SubscriptionsManager] Failed to load subs:", err);
|
||||
userLogger.error("[SubscriptionsManager] Failed to load subs:", err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,18 +115,16 @@ class SubscriptionsManager {
|
||||
throw new Error("No user pubkey => cannot addChannel.");
|
||||
}
|
||||
if (this.subscribedPubkeys.has(channelHex)) {
|
||||
console.log("Already subscribed to", channelHex);
|
||||
devLogger.log("Already subscribed to", channelHex);
|
||||
return;
|
||||
}
|
||||
this.subscribedPubkeys.add(channelHex);
|
||||
await this.publishSubscriptionList(userPubkey);
|
||||
this.refreshActiveFeed({ reason: "subscription-update" }).catch((error) => {
|
||||
if (typeof console !== "undefined") {
|
||||
console.warn(
|
||||
"[SubscriptionsManager] Failed to refresh after adding subscription:",
|
||||
error
|
||||
);
|
||||
}
|
||||
userLogger.warn(
|
||||
"[SubscriptionsManager] Failed to refresh after adding subscription:",
|
||||
error
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -134,18 +133,16 @@ class SubscriptionsManager {
|
||||
throw new Error("No user pubkey => cannot removeChannel.");
|
||||
}
|
||||
if (!this.subscribedPubkeys.has(channelHex)) {
|
||||
console.log("Channel not found in subscription list:", channelHex);
|
||||
devLogger.log("Channel not found in subscription list:", channelHex);
|
||||
return;
|
||||
}
|
||||
this.subscribedPubkeys.delete(channelHex);
|
||||
await this.publishSubscriptionList(userPubkey);
|
||||
this.refreshActiveFeed({ reason: "subscription-update" }).catch((error) => {
|
||||
if (typeof console !== "undefined") {
|
||||
console.warn(
|
||||
"[SubscriptionsManager] Failed to refresh after removing subscription:",
|
||||
error
|
||||
);
|
||||
}
|
||||
userLogger.warn(
|
||||
"[SubscriptionsManager] Failed to refresh after removing subscription:",
|
||||
error
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -173,7 +170,7 @@ class SubscriptionsManager {
|
||||
try {
|
||||
cipherText = await window.nostr.nip04.encrypt(userPubkey, plainStr);
|
||||
} catch (err) {
|
||||
console.error("Encryption failed:", err);
|
||||
userLogger.error("Encryption failed:", err);
|
||||
throw err;
|
||||
}
|
||||
|
||||
@@ -187,7 +184,7 @@ class SubscriptionsManager {
|
||||
try {
|
||||
signedEvent = await window.nostr.signEvent(evt);
|
||||
} catch (signErr) {
|
||||
console.error("Failed to sign subscription list:", signErr);
|
||||
userLogger.error("Failed to sign subscription list:", signErr);
|
||||
throw signErr;
|
||||
}
|
||||
|
||||
@@ -206,7 +203,7 @@ class SubscriptionsManager {
|
||||
if (publishError?.relayFailures?.length) {
|
||||
publishError.relayFailures.forEach(
|
||||
({ url, error: relayError, reason }) => {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
`[SubscriptionsManager] Subscription list rejected by ${url}: ${reason}`,
|
||||
relayError || reason
|
||||
);
|
||||
@@ -224,7 +221,7 @@ class SubscriptionsManager {
|
||||
: relayError
|
||||
? String(relayError)
|
||||
: "publish failed";
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
`[SubscriptionsManager] Subscription list not accepted by ${url}: ${reason}`,
|
||||
relayError
|
||||
);
|
||||
@@ -233,7 +230,7 @@ class SubscriptionsManager {
|
||||
|
||||
this.subsEventId = signedEvent.id;
|
||||
const acceptedUrls = publishSummary.accepted.map(({ url }) => url);
|
||||
console.log(
|
||||
devLogger.log(
|
||||
"Subscription list published, event id:",
|
||||
signedEvent.id,
|
||||
"accepted relays:",
|
||||
@@ -348,7 +345,7 @@ class SubscriptionsManager {
|
||||
this.renderSameGridStyle(result, containerId, { limit, reason });
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"[SubscriptionsManager] Failed to run subscriptions feed:",
|
||||
error
|
||||
);
|
||||
@@ -365,7 +362,7 @@ class SubscriptionsManager {
|
||||
try {
|
||||
app.registerSubscriptionsFeed();
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[SubscriptionsManager] Failed to register subscriptions feed:",
|
||||
error
|
||||
);
|
||||
@@ -607,7 +604,7 @@ class SubscriptionsManager {
|
||||
magnet: detail.magnet
|
||||
})
|
||||
).catch((error) => {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"[SubscriptionsManager] Failed to play by event id:",
|
||||
error
|
||||
);
|
||||
@@ -617,7 +614,7 @@ class SubscriptionsManager {
|
||||
Promise.resolve(
|
||||
app?.playVideoWithFallback?.({ url: detail.url, magnet: detail.magnet })
|
||||
).catch((error) => {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"[SubscriptionsManager] Failed to start playback:",
|
||||
error
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
const STORAGE_KEY = "bitvid:theme";
|
||||
const FALLBACK_THEME = "dark";
|
||||
const VALID_THEMES = new Set(["light", "dark"]);
|
||||
@@ -42,7 +43,7 @@ const readStoredTheme = () => {
|
||||
const stored = window.localStorage.getItem(STORAGE_KEY);
|
||||
return normalizeTheme(stored);
|
||||
} catch (error) {
|
||||
console.warn("Unable to read stored theme preference:", error);
|
||||
userLogger.warn("Unable to read stored theme preference:", error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -54,7 +55,7 @@ const persistTheme = (theme) => {
|
||||
try {
|
||||
window.localStorage.setItem(STORAGE_KEY, theme);
|
||||
} catch (error) {
|
||||
console.warn("Unable to persist theme preference:", error);
|
||||
userLogger.warn("Unable to persist theme preference:", error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -92,7 +93,7 @@ const updateThemeColorMeta = (theme) => {
|
||||
.trim();
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("Unable to compute theme color token:", error);
|
||||
userLogger.warn("Unable to compute theme color token:", error);
|
||||
}
|
||||
|
||||
const fallback = FALLBACK_META_COLORS[theme] || FALLBACK_META_COLORS[FALLBACK_THEME];
|
||||
@@ -179,7 +180,7 @@ const collectToggleElements = (root = document) => {
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn(`Invalid selector for theme toggle: ${selector}`, error);
|
||||
userLogger.warn(`Invalid selector for theme toggle: ${selector}`, error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { createModalAccessibility } from "./modalAccessibility.js";
|
||||
import { Nip71FormManager } from "./nip71FormManager.js";
|
||||
import { userLogger } from "../../utils/logger.js";
|
||||
|
||||
export class UploadModal {
|
||||
constructor({
|
||||
@@ -439,7 +440,7 @@ export class UploadModal {
|
||||
unsubscribe();
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("[UploadModal] Failed to remove R2 listener", error);
|
||||
userLogger.warn("[UploadModal] Failed to remove R2 listener", error);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -855,7 +856,7 @@ export class UploadModal {
|
||||
await this.refreshCloudflareBucketPreview();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[UploadModal] Failed to save Cloudflare settings", error);
|
||||
userLogger.error("[UploadModal] Failed to save Cloudflare settings", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -869,7 +870,7 @@ export class UploadModal {
|
||||
await this.refreshCloudflareBucketPreview();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[UploadModal] Failed to clear Cloudflare settings", error);
|
||||
userLogger.error("[UploadModal] Failed to clear Cloudflare settings", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -934,7 +935,7 @@ export class UploadModal {
|
||||
onReset: () => this.resetCloudflareUploadForm()
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("[UploadModal] Cloudflare upload failed", error);
|
||||
userLogger.error("[UploadModal] Cloudflare upload failed", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -953,7 +954,7 @@ export class UploadModal {
|
||||
cleanup();
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("[UploadModal] Failed to remove handler", error);
|
||||
userLogger.warn("[UploadModal] Failed to remove handler", error);
|
||||
}
|
||||
});
|
||||
this.cleanupHandlers = [];
|
||||
@@ -966,7 +967,7 @@ export class UploadModal {
|
||||
unsubscribe();
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("[UploadModal] Failed to cleanup R2 listener", error);
|
||||
userLogger.warn("[UploadModal] Failed to cleanup R2 listener", error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { updateVideoCardSourceVisibility } from "../../utils/cardSourceVisibilit
|
||||
import positionFloatingPanel from "../utils/positionFloatingPanel.js";
|
||||
import { createFloatingPanelStyles } from "../utils/floatingPanelStyles.js";
|
||||
import {
|
||||
import { userLogger } from "../../utils/logger.js";
|
||||
getPopupOffsetPx,
|
||||
getPopupViewportPaddingPx,
|
||||
} from "../../designSystem/metrics.js";
|
||||
@@ -1566,8 +1567,8 @@ export class VideoCard {
|
||||
const formatted = this.formatters.formatTimeAgo(normalized);
|
||||
return typeof formatted === "string" ? formatted : "";
|
||||
} catch (error) {
|
||||
if (this.window?.console?.warn) {
|
||||
this.window.console.warn(
|
||||
if (this.window?.userLogger?.warn) {
|
||||
this.window.userLogger.warn(
|
||||
"[VideoCard] formatTimeAgo formatter threw",
|
||||
error
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@ import { createModalAccessibility } from "./modalAccessibility.js";
|
||||
import positionFloatingPanel from "../utils/positionFloatingPanel.js";
|
||||
import { createFloatingPanelStyles } from "../utils/floatingPanelStyles.js";
|
||||
import { applyDesignSystemAttributes } from "../../designSystem.js";
|
||||
import { devLogger } from "../../utils/logger.js";
|
||||
import {
|
||||
getPopupOffsetPx,
|
||||
getPopupViewportPaddingPx,
|
||||
@@ -12,7 +13,7 @@ export class VideoModal {
|
||||
removeTrackingScripts,
|
||||
setGlobalModalState,
|
||||
document: doc,
|
||||
logger
|
||||
logger,
|
||||
} = {}) {
|
||||
if (!doc) {
|
||||
throw new Error("VideoModal requires a document reference.");
|
||||
@@ -28,7 +29,14 @@ export class VideoModal {
|
||||
? removeTrackingScripts
|
||||
: () => {};
|
||||
this.setGlobalModalState = setGlobalModalState;
|
||||
this.logger = logger || console;
|
||||
const providedLogger = logger ?? devLogger;
|
||||
if (typeof providedLogger === "function") {
|
||||
this.logger = { log: providedLogger };
|
||||
} else if (providedLogger && typeof providedLogger.log === "function") {
|
||||
this.logger = providedLogger;
|
||||
} else {
|
||||
this.logger = devLogger;
|
||||
}
|
||||
this.eventTarget = new EventTarget();
|
||||
|
||||
this.loaded = false;
|
||||
@@ -101,7 +109,7 @@ export class VideoModal {
|
||||
this.logger(message, ...args);
|
||||
return;
|
||||
}
|
||||
console.log(message, ...args);
|
||||
devLogger.log(message, ...args);
|
||||
}
|
||||
|
||||
addEventListener(type, listener, options) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { userLogger } from "../../utils/logger.js";
|
||||
// NOTE: Keep the Upload, Edit, and Revert modals in lockstep when updating NIP-71 form features.
|
||||
|
||||
const REPEATER_KEYS = ["imeta", "text-track", "segment", "t", "p", "r"];
|
||||
@@ -36,7 +37,7 @@ export class Nip71FormManager {
|
||||
try {
|
||||
store.root.removeEventListener("click", store.handlers.click);
|
||||
} catch (error) {
|
||||
console.warn("[Nip71FormManager] Failed to detach previous handler", error);
|
||||
userLogger.warn("[Nip71FormManager] Failed to detach previous handler", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { normalizeDesignSystemContext } from "../designSystem.js";
|
||||
import positionFloatingPanel from "./utils/positionFloatingPanel.js";
|
||||
import { createFloatingPanelStyles } from "./utils/floatingPanelStyles.js";
|
||||
import {
|
||||
import { userLogger } from "../utils/logger.js";
|
||||
getPopupOffsetPx,
|
||||
getPopupViewportPaddingPx,
|
||||
} from "../designSystem/metrics.js";
|
||||
@@ -460,7 +461,7 @@ export default class MoreMenuController {
|
||||
await this.clipboard.writeText(valueToCopy);
|
||||
this.callbacks.showSuccess("Channel npub copied to clipboard!");
|
||||
} catch (error) {
|
||||
console.error("Failed to copy npub:", error);
|
||||
userLogger.error("Failed to copy npub:", error);
|
||||
this.callbacks.showError("Failed to copy the npub.");
|
||||
}
|
||||
break;
|
||||
@@ -477,7 +478,7 @@ export default class MoreMenuController {
|
||||
try {
|
||||
await this.accessControl?.ensureReady?.();
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"Failed to refresh moderation state before blacklisting:",
|
||||
error,
|
||||
);
|
||||
@@ -521,7 +522,7 @@ export default class MoreMenuController {
|
||||
});
|
||||
} catch (error) {
|
||||
if (this.isDevMode) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[Subscriptions] Failed to refresh after blacklist update:",
|
||||
error,
|
||||
);
|
||||
@@ -552,7 +553,7 @@ export default class MoreMenuController {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to add creator to blacklist:", error);
|
||||
userLogger.error("Failed to add creator to blacklist:", error);
|
||||
this.callbacks.showError(
|
||||
"Failed to update the blacklist. Please try again.",
|
||||
);
|
||||
@@ -608,7 +609,7 @@ export default class MoreMenuController {
|
||||
try {
|
||||
this.callbacks.onUserBlocksUpdated();
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[MoreMenu] Failed to refresh blocked list after update:",
|
||||
error,
|
||||
);
|
||||
@@ -621,14 +622,14 @@ export default class MoreMenuController {
|
||||
});
|
||||
} catch (error) {
|
||||
if (this.isDevMode) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[Subscriptions] Failed to refresh after user block update:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to update personal block list:", error);
|
||||
userLogger.error("Failed to update personal block list:", error);
|
||||
const message =
|
||||
error?.code === "nip04-missing"
|
||||
? "Your Nostr extension must support NIP-04 to manage private lists."
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
MAX_WALLET_DEFAULT_ZAP as CONFIG_MAX_WALLET_DEFAULT_ZAP,
|
||||
} from "../config.js";
|
||||
import { normalizeDesignSystemContext } from "../designSystem.js";
|
||||
import { devLogger, userLogger } from "../utils/logger.js";
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
@@ -940,7 +941,7 @@ export class ProfileModalController {
|
||||
try {
|
||||
this.profileHistoryRenderer = this.createWatchHistoryRenderer(config);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"[profileModal] Failed to create watch history renderer:",
|
||||
error,
|
||||
);
|
||||
@@ -1372,7 +1373,7 @@ export class ProfileModalController {
|
||||
try {
|
||||
await this.switchProfile(entry.pubkey, { entry });
|
||||
} catch (error) {
|
||||
console.error("Failed to switch profile:", error);
|
||||
userLogger.error("Failed to switch profile:", error);
|
||||
} finally {
|
||||
button.dataset.loading = "false";
|
||||
button.setAttribute("aria-busy", "false");
|
||||
@@ -1427,7 +1428,7 @@ export class ProfileModalController {
|
||||
try {
|
||||
this.profileHistoryRenderer?.pause();
|
||||
} catch (error) {
|
||||
console.warn("[profileModal] Failed to pause history renderer:", error);
|
||||
userLogger.warn("[profileModal] Failed to pause history renderer:", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1990,7 +1991,7 @@ export class ProfileModalController {
|
||||
}
|
||||
this.populateBlockedList();
|
||||
} catch (error) {
|
||||
console.error("Failed to add creator to personal block list:", error);
|
||||
userLogger.error("Failed to add creator to personal block list:", error);
|
||||
context.error = error;
|
||||
context.reason = error?.code || "service-error";
|
||||
const message =
|
||||
@@ -2026,7 +2027,7 @@ export class ProfileModalController {
|
||||
}
|
||||
|
||||
if (!targetHex) {
|
||||
console.warn("No valid pubkey to remove from block list:", candidate);
|
||||
userLogger.warn("No valid pubkey to remove from block list:", candidate);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2055,7 +2056,7 @@ export class ProfileModalController {
|
||||
|
||||
this.populateBlockedList();
|
||||
} catch (error) {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"Failed to remove creator from personal block list:",
|
||||
error,
|
||||
);
|
||||
@@ -2111,7 +2112,7 @@ export class ProfileModalController {
|
||||
renderer.resume();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"[profileModal] Failed to populate watch history pane:",
|
||||
error,
|
||||
);
|
||||
@@ -2769,11 +2770,11 @@ export class ProfileModalController {
|
||||
|
||||
if (loadError) {
|
||||
if (loadError?.code === "nostr-unavailable") {
|
||||
console.info("Moderation lists are still syncing with relays.");
|
||||
devLogger.info("Moderation lists are still syncing with relays.");
|
||||
return;
|
||||
}
|
||||
|
||||
console.error("Failed to load admin lists:", loadError);
|
||||
userLogger.error("Failed to load admin lists:", loadError);
|
||||
this.showStatus(null);
|
||||
this.showError("Unable to load moderation lists. Please try again.");
|
||||
this.clearAdminLists();
|
||||
@@ -2866,7 +2867,7 @@ export class ProfileModalController {
|
||||
}
|
||||
} catch (error) {
|
||||
preloadError = error;
|
||||
console.error("Failed to load admin lists before adding moderator:", error);
|
||||
userLogger.error("Failed to load admin lists before adding moderator:", error);
|
||||
}
|
||||
|
||||
if (preloadError) {
|
||||
@@ -2970,7 +2971,7 @@ export class ProfileModalController {
|
||||
}
|
||||
} catch (error) {
|
||||
preloadError = error;
|
||||
console.error("Failed to load admin lists before removing moderator:", error);
|
||||
userLogger.error("Failed to load admin lists before removing moderator:", error);
|
||||
}
|
||||
|
||||
if (preloadError) {
|
||||
@@ -3077,7 +3078,7 @@ export class ProfileModalController {
|
||||
}
|
||||
} catch (error) {
|
||||
preloadError = error;
|
||||
console.error("Failed to load admin lists before updating entries:", error);
|
||||
userLogger.error("Failed to load admin lists before updating entries:", error);
|
||||
}
|
||||
|
||||
if (preloadError) {
|
||||
@@ -3162,7 +3163,7 @@ export class ProfileModalController {
|
||||
this.showError(errorMessage);
|
||||
}
|
||||
if (isDevMode && notifyResult?.error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[admin] Failed to send list notification DM:",
|
||||
notifyResult,
|
||||
);
|
||||
@@ -3178,13 +3179,11 @@ export class ProfileModalController {
|
||||
}
|
||||
} catch (error) {
|
||||
context.notificationError = error;
|
||||
console.error("Failed to send list notification DM:", error);
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"List update succeeded, but DM notification threw an unexpected error.",
|
||||
error,
|
||||
);
|
||||
}
|
||||
userLogger.error("Failed to send list notification DM:", error);
|
||||
devLogger.warn(
|
||||
"List update succeeded, but DM notification threw an unexpected error.",
|
||||
error,
|
||||
);
|
||||
this.notifyAdminError({
|
||||
listType,
|
||||
action,
|
||||
@@ -3468,7 +3467,7 @@ export class ProfileModalController {
|
||||
targetHex,
|
||||
});
|
||||
} catch (refreshError) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[ProfileModalController] Failed to refresh videos after blocklist mutation:",
|
||||
refreshError,
|
||||
);
|
||||
@@ -3776,7 +3775,7 @@ export class ProfileModalController {
|
||||
try {
|
||||
await this.refreshAdminPaneState();
|
||||
} catch (error) {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"Failed to refresh admin pane while opening profile modal:",
|
||||
error,
|
||||
);
|
||||
@@ -3793,7 +3792,7 @@ export class ProfileModalController {
|
||||
const activeHex = this.normalizeHexPubkey(this.getActivePubkey());
|
||||
await this.services.userBlocks.ensureLoaded(activeHex);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"Failed to refresh user block list while opening profile modal:",
|
||||
error,
|
||||
);
|
||||
@@ -3886,7 +3885,7 @@ export class ProfileModalController {
|
||||
this.profileHistoryRenderer.destroy();
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[profileModal] Failed to reset watch history renderer on close:",
|
||||
error,
|
||||
);
|
||||
@@ -3913,7 +3912,7 @@ export class ProfileModalController {
|
||||
try {
|
||||
previous.focus();
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[profileModal] Failed to restore focus after closing modal:",
|
||||
error,
|
||||
);
|
||||
@@ -3926,7 +3925,7 @@ export class ProfileModalController {
|
||||
try {
|
||||
this.callbacks.onClose(this);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[profileModal] onClose callback threw while hiding modal:",
|
||||
error,
|
||||
);
|
||||
@@ -3950,7 +3949,7 @@ export class ProfileModalController {
|
||||
persistActive: false,
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[profileModal] Failed to sync saved profiles during login:",
|
||||
error,
|
||||
);
|
||||
@@ -3970,7 +3969,7 @@ export class ProfileModalController {
|
||||
try {
|
||||
await this.refreshAdminPaneState();
|
||||
} catch (error) {
|
||||
console.warn("Failed to refresh admin pane after login:", error);
|
||||
userLogger.warn("Failed to refresh admin pane after login:", error);
|
||||
}
|
||||
|
||||
this.populateBlockedList();
|
||||
@@ -3984,7 +3983,7 @@ export class ProfileModalController {
|
||||
this.refreshWalletPaneState();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[profileModal] Failed to hydrate deferred login data:",
|
||||
error,
|
||||
);
|
||||
@@ -4004,7 +4003,7 @@ export class ProfileModalController {
|
||||
persistActive: false,
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[profileModal] Failed to sync saved profiles during logout:",
|
||||
error,
|
||||
);
|
||||
@@ -4023,7 +4022,7 @@ export class ProfileModalController {
|
||||
try {
|
||||
await this.refreshAdminPaneState();
|
||||
} catch (error) {
|
||||
console.warn("Failed to refresh admin pane after logout:", error);
|
||||
userLogger.warn("Failed to refresh admin pane after logout:", error);
|
||||
}
|
||||
|
||||
this.populateBlockedList();
|
||||
@@ -4041,7 +4040,7 @@ export class ProfileModalController {
|
||||
persistActive: false,
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[profileModal] Failed to sync saved profiles after profile update:",
|
||||
error,
|
||||
);
|
||||
@@ -4066,7 +4065,7 @@ export class ProfileModalController {
|
||||
try {
|
||||
result = this.services.removeSavedProfile(pubkey) || { removed: false };
|
||||
} catch (error) {
|
||||
console.error("Failed to remove saved profile:", error);
|
||||
userLogger.error("Failed to remove saved profile:", error);
|
||||
result = { removed: false, error };
|
||||
}
|
||||
|
||||
@@ -4099,7 +4098,7 @@ export class ProfileModalController {
|
||||
try {
|
||||
return await hydrate(normalized);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
`[ProfileModalController] Failed to hydrate wallet settings for ${normalized}:`,
|
||||
error,
|
||||
);
|
||||
@@ -4155,7 +4154,7 @@ export class ProfileModalController {
|
||||
try {
|
||||
return this.services.persistSavedProfiles(...args);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[ProfileModalController] Persist saved profiles service threw:",
|
||||
error,
|
||||
);
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
unsubscribeFromVideoViewCount,
|
||||
} from "../../viewCounter.js";
|
||||
import { normalizeDesignSystemContext } from "../../designSystem.js";
|
||||
import { userLogger } from "../../utils/logger.js";
|
||||
|
||||
const EMPTY_VIDEO_LIST_SIGNATURE = "__EMPTY__";
|
||||
|
||||
@@ -539,8 +540,8 @@ export class VideoListView {
|
||||
videoCard.updatePostedAt(Math.floor(resolvedPostedAt));
|
||||
})
|
||||
.catch((error) => {
|
||||
if (this.window?.console?.warn) {
|
||||
this.window.console.warn(
|
||||
if (this.window?.userLogger?.warn) {
|
||||
this.window.userLogger.warn(
|
||||
"[VideoListView] Failed to resolve posted timestamp:",
|
||||
error
|
||||
);
|
||||
@@ -766,7 +767,7 @@ export class VideoListView {
|
||||
try {
|
||||
unsubscribeFromVideoViewCount(entry.pointer, entry.token);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
`[viewCount] Failed to unsubscribe from stale pointer ${key}:`,
|
||||
error
|
||||
);
|
||||
@@ -920,7 +921,7 @@ export class VideoListView {
|
||||
this.viewCountSubscriptions.set(pointerInfo.key, entry);
|
||||
return entry;
|
||||
} catch (error) {
|
||||
console.warn("[viewCount] Failed to subscribe to view counter:", error);
|
||||
userLogger.warn("[viewCount] Failed to subscribe to view counter:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -972,7 +973,7 @@ export class VideoListView {
|
||||
try {
|
||||
unsubscribeFromVideoViewCount(entry.pointer, entry.token);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
`[viewCount] Failed to unsubscribe from pointer ${key}:`,
|
||||
error
|
||||
);
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
pointerKey as derivePointerKey,
|
||||
} from "../nostr.js";
|
||||
import { normalizeDesignSystemContext } from "../designSystem.js";
|
||||
import { devLogger } from "../utils/logger.js";
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
@@ -22,12 +23,10 @@ function safeInvoke(callback, payload) {
|
||||
try {
|
||||
callback(payload);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryController] onStateChange handler failed:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryController] onStateChange handler failed:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,12 +103,10 @@ export default class WatchHistoryController {
|
||||
try {
|
||||
return derivePointerKey(normalized) || "";
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryController] Failed to derive pointer key:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryController] Failed to derive pointer key:",
|
||||
error,
|
||||
);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -321,12 +318,10 @@ export default class WatchHistoryController {
|
||||
source: reason,
|
||||
});
|
||||
} catch (updateError) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryController] Failed to update local watch history list:",
|
||||
updateError,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryController] Failed to update local watch history list:",
|
||||
updateError,
|
||||
);
|
||||
}
|
||||
|
||||
this.showSuccess(
|
||||
@@ -355,14 +350,12 @@ export default class WatchHistoryController {
|
||||
try {
|
||||
const result = this.watchHistoryService.snapshot(undefined, { reason });
|
||||
return Promise.resolve(result).catch((error) => {
|
||||
if (isDevMode) {
|
||||
console.warn(`[${context}] Watch history flush failed:`, error);
|
||||
devLogger.warn(`[${context] Watch history flush failed:`, error);
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(`[${context}] Failed to queue watch history flush:`, error);
|
||||
devLogger.warn(`[${context] Failed to queue watch history flush:`, error);
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
+19
-26
@@ -19,6 +19,7 @@ import {
|
||||
} from "../payments/lnurl.js";
|
||||
import { getPlatformLightningAddress } from "../payments/platformAddress.js";
|
||||
import {
|
||||
import { devLogger, userLogger } from "../utils/logger.js";
|
||||
ensureWallet as ensureWalletDefault,
|
||||
sendPayment as sendPaymentDefault,
|
||||
} from "../payments/nwcClient.js";
|
||||
@@ -118,9 +119,7 @@ export default class ZapController {
|
||||
this.resetFeedback();
|
||||
this.applyDefaultAmount();
|
||||
this.preloadLightningMetadata().catch((error) => {
|
||||
if (isDevMode) {
|
||||
console.warn("[zap] Preload metadata error:", error);
|
||||
}
|
||||
devLogger.warn("[zap] Preload metadata error:", error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -238,7 +237,7 @@ export default class ZapController {
|
||||
Promise.resolve()
|
||||
.then(() => this.requestWalletPane())
|
||||
.catch((error) => {
|
||||
console.error("Failed to open wallet pane:", error);
|
||||
userLogger.error("Failed to open wallet pane:", error);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -312,9 +311,7 @@ export default class ZapController {
|
||||
try {
|
||||
await fetchLightningMetadata(lightningAddress);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn("[zap] Failed to preload creator metadata:", error);
|
||||
}
|
||||
devLogger.warn("[zap] Failed to preload creator metadata:", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,18 +330,14 @@ export default class ZapController {
|
||||
});
|
||||
setCachedPlatformLightningAddress(platformAddress || "");
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn("[zap] Failed to load platform Lightning address:", error);
|
||||
}
|
||||
devLogger.warn("[zap] Failed to load platform Lightning address:", error);
|
||||
}
|
||||
}
|
||||
if (platformAddress) {
|
||||
try {
|
||||
await fetchLightningMetadata(platformAddress);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn("[zap] Failed to preload platform metadata:", error);
|
||||
}
|
||||
devLogger.warn("[zap] Failed to preload platform metadata:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -428,7 +421,7 @@ export default class ZapController {
|
||||
? details.retryAttempt
|
||||
: undefined,
|
||||
};
|
||||
console.error("[zap] Modal zap failure", summary, error);
|
||||
userLogger.error("[zap] Modal zap failure", summary, error);
|
||||
};
|
||||
|
||||
const lightningAddress = this.getCurrentVideo()?.lightningAddress || "";
|
||||
@@ -675,17 +668,17 @@ export default class ZapController {
|
||||
overrideFee,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"[zap] Modal lightning context failed",
|
||||
{
|
||||
amount,
|
||||
overrideFee,
|
||||
commentLength: typeof comment === "string" ? comment.length : undefined,
|
||||
wallet: {
|
||||
hasUri: Boolean(settings?.nwcUri),
|
||||
type:
|
||||
settings?.type || settings?.name || settings?.client || undefined,
|
||||
},
|
||||
amount,
|
||||
overrideFee,
|
||||
commentLength: typeof comment === "string" ? comment.length : undefined,
|
||||
wallet: {
|
||||
hasUri: Boolean(settings?.nwcUri),
|
||||
type:
|
||||
settings?.type || settings?.name || settings?.client || undefined,
|
||||
},
|
||||
},
|
||||
error
|
||||
);
|
||||
@@ -720,7 +713,7 @@ export default class ZapController {
|
||||
if (Array.isArray(shareTracker) && shareTracker.length) {
|
||||
error.__zapShareTracker = shareTracker;
|
||||
}
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"[zap] splitAndZap failed",
|
||||
{
|
||||
amount,
|
||||
@@ -818,7 +811,7 @@ export default class ZapController {
|
||||
const tracker = Array.isArray(error?.__zapShareTracker)
|
||||
? error.__zapShareTracker
|
||||
: [];
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"[zap] Modal zap retry failed",
|
||||
{
|
||||
shareType: share?.type || "unknown",
|
||||
@@ -908,7 +901,7 @@ export default class ZapController {
|
||||
const tracker = Array.isArray(error?.__zapShareTracker)
|
||||
? error.__zapShareTracker
|
||||
: [];
|
||||
console.error(
|
||||
userLogger.error(
|
||||
"[zap] Modal zap attempt failed",
|
||||
{
|
||||
amount,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createCardObserver } from "./dom/cardObserver.js";
|
||||
import { safeDecodeURIComponent } from "./utils/safeDecode.js";
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
|
||||
const ROOT_MARGIN = "0px";
|
||||
const THRESHOLD = 0.25;
|
||||
@@ -49,7 +50,7 @@ const urlCardObserver = createCardObserver({
|
||||
try {
|
||||
state.onCheck({ card, badgeEl, url, eventId });
|
||||
} catch (err) {
|
||||
console.warn("[urlHealthObserver] onCheck handler failed", err);
|
||||
userLogger.warn("[urlHealthObserver] onCheck handler failed", err);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
+12
-11
@@ -2,6 +2,7 @@
|
||||
import { nostrClient } from "./nostr.js";
|
||||
import { buildBlockListEvent, BLOCK_LIST_IDENTIFIER } from "./nostrEventSchemas.js";
|
||||
import {
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
publishEventToRelays,
|
||||
assertAnyRelayAccepted,
|
||||
} from "./nostrPublish.js";
|
||||
@@ -74,7 +75,7 @@ class UserBlockListManager {
|
||||
}
|
||||
|
||||
if (!window?.nostr?.nip04?.decrypt) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[UserBlockList] nip04.decrypt is unavailable; treating block list as empty."
|
||||
);
|
||||
this.reset();
|
||||
@@ -202,7 +203,7 @@ class UserBlockListManager {
|
||||
try {
|
||||
decrypted = await window.nostr.nip04.decrypt(normalized, newest.content);
|
||||
} catch (err) {
|
||||
console.error("[UserBlockList] Failed to decrypt block list:", err);
|
||||
userLogger.error("[UserBlockList] Failed to decrypt block list:", err);
|
||||
this.blockedPubkeys.clear();
|
||||
return;
|
||||
}
|
||||
@@ -225,7 +226,7 @@ class UserBlockListManager {
|
||||
});
|
||||
this.blockedPubkeys = new Set(sanitized);
|
||||
} catch (err) {
|
||||
console.error("[UserBlockList] Failed to parse block list:", err);
|
||||
userLogger.error("[UserBlockList] Failed to parse block list:", err);
|
||||
this.blockedPubkeys.clear();
|
||||
}
|
||||
};
|
||||
@@ -247,12 +248,12 @@ class UserBlockListManager {
|
||||
} else {
|
||||
const reason = outcome.reason;
|
||||
if (reason?.code === "timeout") {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
`[UserBlockList] Relay ${reason.relay} timed out while loading block list (${reason.timeoutMs}ms)`
|
||||
);
|
||||
} else {
|
||||
const relay = reason?.relay || reason?.relayUrl;
|
||||
console.error(
|
||||
userLogger.error(
|
||||
`[UserBlockList] Relay error at ${relay}:`,
|
||||
reason?.error ?? reason
|
||||
);
|
||||
@@ -267,7 +268,7 @@ class UserBlockListManager {
|
||||
await applyEvents(aggregated, { skipIfEmpty: true });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("[UserBlockList] background block list refresh failed:", error);
|
||||
userLogger.error("[UserBlockList] background block list refresh failed:", error);
|
||||
});
|
||||
|
||||
let fastResult = null;
|
||||
@@ -278,13 +279,13 @@ class UserBlockListManager {
|
||||
if (error instanceof AggregateError) {
|
||||
error.errors?.forEach((err) => {
|
||||
if (err?.code === "timeout") {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
`[UserBlockList] Relay ${err.relay} timed out while loading block list (${err.timeoutMs}ms)`
|
||||
);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error("[UserBlockList] Fast block list fetch failed:", error);
|
||||
userLogger.error("[UserBlockList] Fast block list fetch failed:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -299,7 +300,7 @@ class UserBlockListManager {
|
||||
this.blockEventId = null;
|
||||
background.catch(() => {});
|
||||
} catch (error) {
|
||||
console.error("[UserBlockList] loadBlocks failed:", error);
|
||||
userLogger.error("[UserBlockList] loadBlocks failed:", error);
|
||||
this.blockedPubkeys.clear();
|
||||
} finally {
|
||||
this.loaded = true;
|
||||
@@ -431,7 +432,7 @@ class UserBlockListManager {
|
||||
if (publishError?.relayFailures?.length) {
|
||||
publishError.relayFailures.forEach(
|
||||
({ url, error: relayError, reason }) => {
|
||||
console.error(
|
||||
userLogger.error(
|
||||
`[UserBlockList] Block list rejected by ${url}: ${reason}`,
|
||||
relayError || reason
|
||||
);
|
||||
@@ -449,7 +450,7 @@ class UserBlockListManager {
|
||||
: relayError
|
||||
? String(relayError)
|
||||
: "publish failed";
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
`[UserBlockList] Block list not accepted by ${url}: ${reason}`,
|
||||
relayError
|
||||
);
|
||||
|
||||
+4
-3
@@ -1,3 +1,4 @@
|
||||
import { userLogger } from "./logger.js";
|
||||
// js/utils/storage.js
|
||||
|
||||
const URL_HEALTH_STORAGE_PREFIX = "bitvid:urlHealth:";
|
||||
@@ -21,7 +22,7 @@ export function readUrlHealthFromStorage(eventId) {
|
||||
return parsed;
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(`Failed to parse stored URL health for ${eventId}:`, err);
|
||||
userLogger.warn(`Failed to parse stored URL health for ${eventId}:`, err);
|
||||
}
|
||||
|
||||
removeUrlHealthFromStorage(eventId);
|
||||
@@ -39,7 +40,7 @@ export function writeUrlHealthToStorage(eventId, entry) {
|
||||
JSON.stringify(entry)
|
||||
);
|
||||
} catch (err) {
|
||||
console.warn(`Failed to persist URL health for ${eventId}:`, err);
|
||||
userLogger.warn(`Failed to persist URL health for ${eventId}:`, err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +52,6 @@ export function removeUrlHealthFromStorage(eventId) {
|
||||
try {
|
||||
localStorage.removeItem(getUrlHealthStorageKey(eventId));
|
||||
} catch (err) {
|
||||
console.warn(`Failed to remove URL health for ${eventId}:`, err);
|
||||
userLogger.warn(`Failed to remove URL health for ${eventId}:`, err);
|
||||
}
|
||||
}
|
||||
+12
-11
@@ -17,6 +17,7 @@ import {
|
||||
VIEW_COUNT_DEDUPE_WINDOW_SECONDS,
|
||||
} from "./config.js";
|
||||
import {
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
countVideoViewEvents,
|
||||
listVideoViewEvents,
|
||||
subscribeVideoViewEvents,
|
||||
@@ -164,7 +165,7 @@ function normalizePointer(pointer) {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("[viewCounter] Failed to decode NIP-19 pointer:", error);
|
||||
userLogger.warn("[viewCounter] Failed to decode NIP-19 pointer:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,7 +280,7 @@ function restoreCacheSnapshot() {
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("[viewCounter] Failed to restore cached view counts:", error);
|
||||
userLogger.warn("[viewCounter] Failed to restore cached view counts:", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,7 +308,7 @@ function persistCacheSnapshot() {
|
||||
};
|
||||
localStorage.setItem(VIEW_COUNTER_STORAGE_KEY, JSON.stringify(payload));
|
||||
} catch (error) {
|
||||
console.warn("[viewCounter] Failed to persist view count cache:", error);
|
||||
userLogger.warn("[viewCounter] Failed to persist view count cache:", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,7 +377,7 @@ function notifyHandlers(key) {
|
||||
try {
|
||||
handler(snapshot);
|
||||
} catch (error) {
|
||||
console.warn("[viewCounter] View handler threw:", error);
|
||||
userLogger.warn("[viewCounter] View handler threw:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -468,15 +469,15 @@ async function hydratePointer(key, listeners) {
|
||||
try {
|
||||
listResult = await listPromise;
|
||||
} catch (error) {
|
||||
console.warn("[viewCounter] Failed to hydrate view events via list:", error);
|
||||
userLogger.warn("[viewCounter] Failed to hydrate view events via list:", error);
|
||||
}
|
||||
try {
|
||||
countResult = await countPromise;
|
||||
} catch (error) {
|
||||
if (error?.name === "AbortError") {
|
||||
console.warn("[viewCounter] View count hydration aborted:", error);
|
||||
userLogger.warn("[viewCounter] View count hydration aborted:", error);
|
||||
} else {
|
||||
console.warn("[viewCounter] Failed to count view events:", error);
|
||||
userLogger.warn("[viewCounter] Failed to count view events:", error);
|
||||
}
|
||||
}
|
||||
let mutated = false;
|
||||
@@ -549,7 +550,7 @@ function ensureLiveSubscription(key, listeners) {
|
||||
try {
|
||||
unsubscribe();
|
||||
} catch (error) {
|
||||
console.warn("[viewCounter] Failed to unsubscribe from view events:", error);
|
||||
userLogger.warn("[viewCounter] Failed to unsubscribe from view events:", error);
|
||||
}
|
||||
listeners.liveUnsub = null;
|
||||
if (!listeners.hydrationPromise) {
|
||||
@@ -558,7 +559,7 @@ function ensureLiveSubscription(key, listeners) {
|
||||
};
|
||||
setPointerStatus(key, "live");
|
||||
} catch (error) {
|
||||
console.warn("[viewCounter] Failed to open live view subscription:", error);
|
||||
userLogger.warn("[viewCounter] Failed to open live view subscription:", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,7 +584,7 @@ export function subscribeToVideoViewCount(pointerInput, handler, options = {}) {
|
||||
status: state.status,
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn("[viewCounter] Initial handler invocation threw:", error);
|
||||
userLogger.warn("[viewCounter] Initial handler invocation threw:", error);
|
||||
}
|
||||
ensureHydration(key, listeners);
|
||||
ensureLiveSubscription(key, listeners);
|
||||
@@ -617,7 +618,7 @@ export function ingestLocalViewEvent({ event, pointer }) {
|
||||
notifyHandlers(key);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("[viewCounter] Failed to ingest local view event:", error);
|
||||
userLogger.warn("[viewCounter] Failed to ingest local view event:", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -4,6 +4,7 @@ import { subscriptions } from "./subscriptions.js";
|
||||
import { getApplication } from "./applicationContext.js";
|
||||
import { ASSET_VERSION } from "../config/asset-version.js";
|
||||
import { applyDesignSystemAttributes } from "./designSystem.js";
|
||||
import { devLogger, userLogger } from "./utils/logger.js";
|
||||
|
||||
const TRACKING_SCRIPT_PATTERN = /(?:^|\/)tracking\.js(?:$|\?)/;
|
||||
|
||||
@@ -55,7 +56,7 @@ export async function loadView(viewUrl) {
|
||||
container.appendChild(newScript);
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("View loading error:", err);
|
||||
userLogger.error("View loading error:", err);
|
||||
const fallbackMarkup = `
|
||||
<div class="bv-stack">
|
||||
<article class="card p-md" data-state="critical">
|
||||
@@ -92,7 +93,7 @@ export const viewInitRegistry = {
|
||||
}
|
||||
},
|
||||
explore: () => {
|
||||
console.log("Explore view loaded.");
|
||||
devLogger.log("Explore view loaded.");
|
||||
},
|
||||
history: async () => {
|
||||
try {
|
||||
@@ -101,7 +102,7 @@ export const viewInitRegistry = {
|
||||
await module.initHistoryView();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to initialize history view:", error);
|
||||
userLogger.error("Failed to initialize history view:", error);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -111,7 +112,7 @@ export const viewInitRegistry = {
|
||||
* which loads subs if needed and renders the video grid in #subscriptionsVideoList
|
||||
*/
|
||||
subscriptions: async () => {
|
||||
console.log("Subscriptions view loaded.");
|
||||
devLogger.log("Subscriptions view loaded.");
|
||||
|
||||
const app = getApplication();
|
||||
if (!app?.pubkey) {
|
||||
|
||||
+10
-20
@@ -1,5 +1,7 @@
|
||||
// js/watchHistoryDebug.js
|
||||
|
||||
import { devLogger } from "./utils/logger.js";
|
||||
|
||||
const WATCH_HISTORY_DEBUG_STORAGE_KEY =
|
||||
"bitvid:debug:watch-history";
|
||||
|
||||
@@ -168,36 +170,24 @@ export function logWatchHistoryDebug(namespace, level, message, details) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scopeConsole =
|
||||
(globalScope && globalScope.console) || (typeof console !== "undefined" ? console : null);
|
||||
if (!scopeConsole) {
|
||||
return;
|
||||
}
|
||||
|
||||
const methodName =
|
||||
typeof level === "string" && level && typeof scopeConsole[level] === "function"
|
||||
typeof level === "string" && level && typeof devLogger[level] === "function"
|
||||
? level
|
||||
: typeof scopeConsole.info === "function"
|
||||
? "info"
|
||||
: "log";
|
||||
: typeof devLogger.info === "function"
|
||||
? "info"
|
||||
: "log";
|
||||
|
||||
const prefix = namespace ? `[${namespace}] ${message}` : message;
|
||||
|
||||
try {
|
||||
if (details && typeof details === "object") {
|
||||
scopeConsole[methodName](prefix, details);
|
||||
devLogger[methodName](prefix, details);
|
||||
} else {
|
||||
scopeConsole[methodName](prefix);
|
||||
devLogger[methodName](prefix);
|
||||
}
|
||||
} catch (error) {
|
||||
try {
|
||||
if (details && typeof details === "object") {
|
||||
scopeConsole.log(prefix, details);
|
||||
} else {
|
||||
scopeConsole.log(prefix);
|
||||
}
|
||||
} catch (fallbackError) {
|
||||
// Swallow logging errors entirely.
|
||||
if (typeof devLogger.log === "function") {
|
||||
devLogger.log(prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
+138
-185
@@ -16,6 +16,7 @@ import {
|
||||
} from "./constants.js";
|
||||
import { isDevMode } from "./config.js";
|
||||
import { getApplication } from "./applicationContext.js";
|
||||
import { devLogger, userLogger } from "./utils/logger.js";
|
||||
|
||||
const SESSION_STORAGE_KEY = "bitvid:watch-history:session:v1";
|
||||
const SESSION_STORAGE_VERSION = 1;
|
||||
@@ -43,12 +44,10 @@ function resolveFlagEnabled() {
|
||||
return getWatchHistoryV2Enabled() === true;
|
||||
}
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryService] Failed to read FEATURE_WATCH_HISTORY_V2 flag:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryService] Failed to read FEATURE_WATCH_HISTORY_V2 flag:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
return FEATURE_WATCH_HISTORY_V2 === true;
|
||||
}
|
||||
@@ -72,12 +71,10 @@ function getLoggedInActorKey() {
|
||||
return normalizeActorKey(normalized);
|
||||
}
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryService] Failed to normalize app login pubkey:",
|
||||
error
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryService] Failed to normalize app login pubkey:",
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,9 +165,7 @@ function getSessionStorage() {
|
||||
return window.sessionStorage;
|
||||
}
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn("[watchHistoryService] sessionStorage unavailable:", error);
|
||||
}
|
||||
devLogger.warn("[watchHistoryService] sessionStorage unavailable:", error);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -181,9 +176,7 @@ function getLocalStorage() {
|
||||
return window.localStorage;
|
||||
}
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn("[watchHistoryService] localStorage unavailable:", error);
|
||||
}
|
||||
devLogger.warn("[watchHistoryService] localStorage unavailable:", error);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -205,12 +198,10 @@ function ensureMetadataPreference() {
|
||||
state.metadata.preference = stored === "true";
|
||||
}
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryService] Failed to read metadata preference:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryService] Failed to read metadata preference:",
|
||||
error,
|
||||
);
|
||||
state.metadata.preference = true;
|
||||
}
|
||||
return state.metadata.preference;
|
||||
@@ -228,12 +219,10 @@ function persistMetadataPreference(value) {
|
||||
storage.setItem(METADATA_PREFERENCE_KEY, "false");
|
||||
}
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryService] Failed to persist metadata preference:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryService] Failed to persist metadata preference:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,12 +304,10 @@ function restoreMetadataCache() {
|
||||
try {
|
||||
raw = storage.getItem(METADATA_STORAGE_KEY);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryService] Failed to read metadata cache:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryService] Failed to read metadata cache:",
|
||||
error,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -332,21 +319,17 @@ function restoreMetadataCache() {
|
||||
try {
|
||||
parsed = JSON.parse(raw);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryService] Failed to parse metadata cache:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryService] Failed to parse metadata cache:",
|
||||
error,
|
||||
);
|
||||
try {
|
||||
storage.removeItem(METADATA_STORAGE_KEY);
|
||||
} catch (cleanupError) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryService] Failed to clear corrupt metadata cache:",
|
||||
cleanupError,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryService] Failed to clear corrupt metadata cache:",
|
||||
cleanupError,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -355,12 +338,10 @@ function restoreMetadataCache() {
|
||||
try {
|
||||
storage.removeItem(METADATA_STORAGE_KEY);
|
||||
} catch (cleanupError) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryService] Failed to clear outdated metadata cache:",
|
||||
cleanupError,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryService] Failed to clear outdated metadata cache:",
|
||||
cleanupError,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -428,12 +409,10 @@ function persistMetadataCache() {
|
||||
try {
|
||||
storage.removeItem(METADATA_STORAGE_KEY);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryService] Failed to clear metadata cache:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryService] Failed to clear metadata cache:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -449,12 +428,10 @@ function persistMetadataCache() {
|
||||
try {
|
||||
storage.setItem(METADATA_STORAGE_KEY, JSON.stringify(payload));
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryService] Failed to persist metadata cache:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryService] Failed to persist metadata cache:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -550,12 +527,10 @@ function emit(eventName, payload) {
|
||||
try {
|
||||
callback(payload);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
`[watchHistoryService] Listener for ${eventName} failed:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
`[watchHistoryService] Listener for ${eventName} failed:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -566,12 +541,10 @@ function emit(eventName, payload) {
|
||||
try {
|
||||
callback({ event: eventName, payload });
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
`[watchHistoryService] Wildcard listener error for ${eventName}:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
`[watchHistoryService] Wildcard listener error for ${eventName}:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -582,12 +555,10 @@ function emit(eventName, payload) {
|
||||
const evt = new CustomEvent("bitvid:watchHistory", { detail });
|
||||
window.dispatchEvent(evt);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
`[watchHistoryService] Failed to dispatch window event for ${eventName}:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
`[watchHistoryService] Failed to dispatch window event for ${eventName}:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -639,9 +610,7 @@ function restoreQueueState() {
|
||||
try {
|
||||
raw = storage.getItem(SESSION_STORAGE_KEY);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn("[watchHistoryService] Failed to read session cache:", error);
|
||||
}
|
||||
devLogger.warn("[watchHistoryService] Failed to read session cache:", error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -653,18 +622,14 @@ function restoreQueueState() {
|
||||
try {
|
||||
parsed = JSON.parse(raw);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn("[watchHistoryService] Failed to parse session cache:", error);
|
||||
}
|
||||
devLogger.warn("[watchHistoryService] Failed to parse session cache:", error);
|
||||
try {
|
||||
storage.removeItem(SESSION_STORAGE_KEY);
|
||||
} catch (cleanupError) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryService] Failed to clear corrupt session cache:",
|
||||
cleanupError
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryService] Failed to clear corrupt session cache:",
|
||||
cleanupError
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -673,12 +638,10 @@ function restoreQueueState() {
|
||||
try {
|
||||
storage.removeItem(SESSION_STORAGE_KEY);
|
||||
} catch (cleanupError) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryService] Failed to clear outdated session cache:",
|
||||
cleanupError
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryService] Failed to clear outdated session cache:",
|
||||
cleanupError
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -770,12 +733,10 @@ function persistQueueState() {
|
||||
try {
|
||||
storage.removeItem(SESSION_STORAGE_KEY);
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn(
|
||||
"[watchHistoryService] Failed to clear empty session cache:",
|
||||
error
|
||||
);
|
||||
}
|
||||
devLogger.warn(
|
||||
"[watchHistoryService] Failed to clear empty session cache:",
|
||||
error
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -783,9 +744,7 @@ function persistQueueState() {
|
||||
try {
|
||||
storage.setItem(SESSION_STORAGE_KEY, JSON.stringify(payload));
|
||||
} catch (error) {
|
||||
if (isDevMode) {
|
||||
console.warn("[watchHistoryService] Failed to persist session cache:", error);
|
||||
}
|
||||
devLogger.warn("[watchHistoryService] Failed to persist session cache:", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -978,18 +937,18 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
|
||||
|
||||
const viewResult = await nostrClient.recordVideoView(pointerInput, recordOptions);
|
||||
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] Video view recorded. Preparing watch list update.",
|
||||
{
|
||||
pointer: pointerInput,
|
||||
createdAt,
|
||||
hasMetadata: !!metadata,
|
||||
pointer: pointerInput,
|
||||
createdAt,
|
||||
hasMetadata: !!metadata,
|
||||
}
|
||||
);
|
||||
|
||||
const pointer = normalizePointerInput(pointerInput);
|
||||
if (!pointer) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[watchHistoryService] Skipping watch list update because pointer normalization failed.",
|
||||
{ pointerInput }
|
||||
);
|
||||
@@ -1004,7 +963,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
|
||||
"";
|
||||
const actorKey = normalizeActorKey(actorCandidate);
|
||||
if (!actorKey) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[watchHistoryService] Unable to resolve actor for watch list update.",
|
||||
{ actorCandidate }
|
||||
);
|
||||
@@ -1013,7 +972,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
|
||||
|
||||
const queue = ensureQueue(actorKey);
|
||||
if (!queue) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[watchHistoryService] Failed to resolve queue for actor.",
|
||||
{ actorKey }
|
||||
);
|
||||
@@ -1024,7 +983,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
|
||||
|
||||
const normalizedPointer = normalizePointerInput(pointer);
|
||||
if (!normalizedPointer) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[watchHistoryService] Pointer normalization failed during queue preparation.",
|
||||
{ pointerInput }
|
||||
);
|
||||
@@ -1064,14 +1023,14 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
|
||||
}
|
||||
|
||||
const key = pointerKey(normalizedPointer);
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] Watch list process triggered by video view.",
|
||||
{
|
||||
actor: actorKey,
|
||||
pointerKey: key,
|
||||
watchedAt: normalizedPointer.watchedAt,
|
||||
sessionEvent: normalizedPointer.session === true,
|
||||
remoteSyncEnabled: remoteEnabled,
|
||||
actor: actorKey,
|
||||
pointerKey: key,
|
||||
watchedAt: normalizedPointer.watchedAt,
|
||||
sessionEvent: normalizedPointer.session === true,
|
||||
remoteSyncEnabled: remoteEnabled,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1084,7 +1043,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
|
||||
}
|
||||
|
||||
if (!key) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"[watchHistoryService] Pointer key generation failed. Skipping queue update.",
|
||||
{ pointer: normalizedPointer }
|
||||
);
|
||||
@@ -1114,12 +1073,12 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
|
||||
queue.throttle.set(key, now);
|
||||
persistQueueState();
|
||||
notifyQueueChange(actorKey);
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] Updated existing watch list entry.",
|
||||
{
|
||||
actor: actorKey,
|
||||
pointerKey: key,
|
||||
watchedAt: existing.pointer.watchedAt,
|
||||
actor: actorKey,
|
||||
pointerKey: key,
|
||||
watchedAt: existing.pointer.watchedAt,
|
||||
}
|
||||
);
|
||||
return viewResult;
|
||||
@@ -1127,11 +1086,9 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
|
||||
|
||||
if (throttled) {
|
||||
queue.throttle.set(key, now);
|
||||
if (isDevMode) {
|
||||
console.info(
|
||||
`[watchHistoryService] Throttled pointer ${key} for actor ${actorKey}.`
|
||||
);
|
||||
}
|
||||
devLogger.info(
|
||||
`[watchHistoryService] Throttled pointer ${key} for actor ${actorKey}.`
|
||||
);
|
||||
return viewResult;
|
||||
}
|
||||
|
||||
@@ -1144,17 +1101,17 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
|
||||
persistQueueState();
|
||||
notifyQueueChange(actorKey);
|
||||
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] Added pointer to pending watch list snapshot queue.",
|
||||
{
|
||||
actor: actorKey,
|
||||
pointerKey: key,
|
||||
queueSize: queue.items.size,
|
||||
actor: actorKey,
|
||||
pointerKey: key,
|
||||
queueSize: queue.items.size,
|
||||
}
|
||||
);
|
||||
|
||||
if (!remoteEnabled) {
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] Watch history sync unavailable for this actor; retaining pointer in local session queue only.",
|
||||
{
|
||||
actor: actorKey,
|
||||
@@ -1175,12 +1132,12 @@ async function snapshot(items, options = {}) {
|
||||
}
|
||||
|
||||
if (!isFeatureEnabled(actorKey)) {
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] Snapshot skipped because watch history sync is unavailable for this actor.",
|
||||
{
|
||||
actor: actorKey,
|
||||
requestedItems: Array.isArray(items) ? items.length : 0,
|
||||
reason,
|
||||
actor: actorKey,
|
||||
requestedItems: Array.isArray(items) ? items.length : 0,
|
||||
reason,
|
||||
}
|
||||
);
|
||||
return { ok: true, skipped: true, reason: "feature-disabled" };
|
||||
@@ -1207,13 +1164,13 @@ async function snapshot(items, options = {}) {
|
||||
|
||||
const queue = ensureQueue(actorKey);
|
||||
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] Initiating watch list snapshot publish.",
|
||||
{
|
||||
actor: actorKey,
|
||||
reason,
|
||||
itemCount: payloadItems.length,
|
||||
queued: queue?.items?.size ?? 0,
|
||||
actor: actorKey,
|
||||
reason,
|
||||
itemCount: payloadItems.length,
|
||||
queued: queue?.items?.size ?? 0,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1227,14 +1184,14 @@ async function snapshot(items, options = {}) {
|
||||
}
|
||||
);
|
||||
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] Watch list snapshot publish completed.",
|
||||
{
|
||||
actor: actorKey,
|
||||
reason,
|
||||
success: !!publishResult?.ok,
|
||||
snapshotId: publishResult?.snapshotId || null,
|
||||
retryable: !!publishResult?.retryable,
|
||||
actor: actorKey,
|
||||
reason,
|
||||
success: !!publishResult?.ok,
|
||||
snapshotId: publishResult?.snapshotId || null,
|
||||
retryable: !!publishResult?.retryable,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1264,20 +1221,18 @@ async function snapshot(items, options = {}) {
|
||||
|
||||
await updateFingerprintCache(actorKey, publishResult.items || payloadItems);
|
||||
emit("snapshot-complete", { actor: actorKey, reason, result: publishResult });
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] Watch list snapshot processed and fingerprint cache updated.",
|
||||
{
|
||||
actor: actorKey,
|
||||
reason,
|
||||
fingerprintUpdated: true,
|
||||
actor: actorKey,
|
||||
reason,
|
||||
fingerprintUpdated: true,
|
||||
}
|
||||
);
|
||||
return publishResult;
|
||||
})()
|
||||
.catch((error) => {
|
||||
if (isDevMode) {
|
||||
console.warn("[watchHistoryService] Snapshot failed:", error);
|
||||
}
|
||||
devLogger.warn("[watchHistoryService] Snapshot failed:", error);
|
||||
throw error;
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -1305,9 +1260,7 @@ function scheduleWatchHistoryRefresh(actorKey, cacheEntry = {}) {
|
||||
return latest?.items || [];
|
||||
})
|
||||
.catch((error) => {
|
||||
if (isDevMode) {
|
||||
console.warn("[watchHistoryService] Failed to load watch history:", error);
|
||||
}
|
||||
devLogger.warn("[watchHistoryService] Failed to load watch history:", error);
|
||||
throw error;
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -1317,9 +1270,9 @@ function scheduleWatchHistoryRefresh(actorKey, cacheEntry = {}) {
|
||||
}
|
||||
});
|
||||
|
||||
console.info("[watchHistoryService] Triggered nostr watch list refresh.", {
|
||||
devLogger.info("[watchHistoryService] Triggered nostr watch list refresh.", {
|
||||
actor: actorKey,
|
||||
});
|
||||
});
|
||||
|
||||
const baseEntry = cacheEntry && typeof cacheEntry === "object" ? cacheEntry : {};
|
||||
state.fingerprintCache.set(actorKey, {
|
||||
@@ -1348,11 +1301,11 @@ async function loadLatest(actorInput, options = {}) {
|
||||
restoreQueueState();
|
||||
}
|
||||
const items = collectQueueItems(actorKey);
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] loadLatest returning local-only watch history queue.",
|
||||
{
|
||||
actor: actorKey,
|
||||
itemCount: items.length,
|
||||
actor: actorKey,
|
||||
itemCount: items.length,
|
||||
}
|
||||
);
|
||||
return items;
|
||||
@@ -1360,12 +1313,12 @@ async function loadLatest(actorInput, options = {}) {
|
||||
|
||||
const now = Date.now();
|
||||
const cacheEntry = state.fingerprintCache.get(actorKey);
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] loadLatest invoked.",
|
||||
{
|
||||
actor: actorKey,
|
||||
cacheHasItems: Array.isArray(cacheEntry?.items),
|
||||
cacheExpiresAt: cacheEntry?.expiresAt || null,
|
||||
actor: actorKey,
|
||||
cacheHasItems: Array.isArray(cacheEntry?.items),
|
||||
cacheExpiresAt: cacheEntry?.expiresAt || null,
|
||||
}
|
||||
);
|
||||
const hasCachedItems = Array.isArray(cacheEntry?.items);
|
||||
@@ -1375,29 +1328,29 @@ async function loadLatest(actorInput, options = {}) {
|
||||
cacheEntry.expiresAt > now;
|
||||
|
||||
if (cacheIsFresh) {
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] Returning cached watch list items.",
|
||||
{
|
||||
actor: actorKey,
|
||||
itemCount: cacheEntry.items.length,
|
||||
actor: actorKey,
|
||||
itemCount: cacheEntry.items.length,
|
||||
}
|
||||
);
|
||||
return cacheEntry.items;
|
||||
}
|
||||
|
||||
if (cacheEntry?.promise) {
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] Awaiting in-flight watch list refresh.",
|
||||
{
|
||||
actor: actorKey,
|
||||
actor: actorKey,
|
||||
}
|
||||
);
|
||||
if (allowStale && hasCachedItems) {
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] Returning stale watch list items while refresh completes.",
|
||||
{
|
||||
actor: actorKey,
|
||||
itemCount: cacheEntry.items.length,
|
||||
actor: actorKey,
|
||||
itemCount: cacheEntry.items.length,
|
||||
}
|
||||
);
|
||||
return cacheEntry.items;
|
||||
@@ -1412,11 +1365,11 @@ async function loadLatest(actorInput, options = {}) {
|
||||
const refreshPromise = scheduleWatchHistoryRefresh(actorKey, cacheEntry);
|
||||
refreshPromise.catch(() => {});
|
||||
|
||||
console.info(
|
||||
devLogger.info(
|
||||
"[watchHistoryService] Returning stale watch list items while refresh is pending.",
|
||||
{
|
||||
actor: actorKey,
|
||||
itemCount: cacheEntry?.items?.length || 0,
|
||||
actor: actorKey,
|
||||
itemCount: cacheEntry?.items?.length || 0,
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
+5
-4
@@ -3,6 +3,7 @@
|
||||
import WebTorrent from "./webtorrent.min.js";
|
||||
import { WSS_TRACKERS } from "./constants.js";
|
||||
import { safeDecodeURIComponent } from "./utils/safeDecode.js";
|
||||
import { devLogger, userLogger } from "./utils/logger.js";
|
||||
|
||||
const DEFAULT_PROBE_TRACKERS = Object.freeze([...WSS_TRACKERS]);
|
||||
|
||||
@@ -288,7 +289,7 @@ export class TorrentClient {
|
||||
}
|
||||
|
||||
log(msg) {
|
||||
console.log(msg);
|
||||
devLogger.log(msg);
|
||||
}
|
||||
|
||||
async isBrave() {
|
||||
@@ -608,20 +609,20 @@ export class TorrentClient {
|
||||
err.message.includes("CORS") ||
|
||||
err.message.includes("Access-Control-Allow-Origin")
|
||||
) {
|
||||
console.warn(
|
||||
userLogger.warn(
|
||||
"CORS warning detected. Attempting to remove the failing webseed/tracker."
|
||||
);
|
||||
if (torrent._opts?.urlList?.length) {
|
||||
torrent._opts.urlList = torrent._opts.urlList.filter((url) => {
|
||||
return !url.includes("distribution.bbb3d.renderfarming.net");
|
||||
});
|
||||
console.warn("Cleaned up webseeds =>", torrent._opts.urlList);
|
||||
userLogger.warn("Cleaned up webseeds =>", torrent._opts.urlList);
|
||||
}
|
||||
if (torrent._opts?.announce?.length) {
|
||||
torrent._opts.announce = torrent._opts.announce.filter((url) => {
|
||||
return !url.includes("fastcast.nz");
|
||||
});
|
||||
console.warn("Cleaned up trackers =>", torrent._opts.announce);
|
||||
userLogger.warn("Cleaned up trackers =>", torrent._opts.announce);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user