From a084bb59de233e5a1fc3ace4e799916644d847ec Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 7 Feb 2026 21:52:51 +0000 Subject: [PATCH 1/2] refactor: deduplicate HEX64_REGEX to js/utils/hex.js Moves the repeatedly defined HEX64_REGEX constant to a shared utility module to improve maintainability and consistency. Updates all consumers to import from the new location. Signed-off-by: Jules Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- js/app.js | 3 ++- js/directMessagesStore.js | 3 ++- js/dmDecryptor.js | 3 ++- js/embed.js | 3 ++- js/nostr/adapters/nsecAdapter.js | 3 ++- js/nostr/client.js | 2 +- js/nostr/dmDecryptWorker.js | 3 ++- js/nostr/nip46Client.js | 3 +-- js/nostr/publishHelpers.js | 3 ++- js/nostr/signerHelpers.js | 2 +- js/nwcSettings.js | 3 ++- js/payments/nwcClient.js | 3 ++- js/payments/platformAddress.js | 3 ++- js/payments/zapSplit.js | 3 ++- js/services/authService.js | 3 ++- js/services/hashtagPreferencesService.js | 3 ++- js/services/profileMetadataService.js | 3 ++- js/state/cache.js | 3 ++- js/ui/components/VideoCard.js | 3 ++- js/ui/components/VideoModal.js | 3 ++- js/utils/hex.js | 2 ++ js/utils/profileBatchFetcher.js | 3 ++- tests/app/is-user-logged-in.test.mjs | 3 ++- 23 files changed, 43 insertions(+), 23 deletions(-) diff --git a/js/app.js b/js/app.js index f568078e..02e3f475 100644 --- a/js/app.js +++ b/js/app.js @@ -190,6 +190,7 @@ import { createPlaybackCoordinator } from "./app/playbackCoordinator.js"; import { createAuthSessionCoordinator } from "./app/authSessionCoordinator.js"; import { createModalCoordinator } from "./app/modalCoordinator.js"; import { createModerationCoordinator } from "./app/moderationCoordinator.js"; +import { HEX64_REGEX } from "./utils/hex.js"; const recordVideoViewApi = (...args) => recordVideoView(nostrClient, ...args); @@ -198,7 +199,7 @@ const UNSUPPORTED_BTITH_MESSAGE = const FALLBACK_THUMBNAIL_SRC = "/assets/jpg/video-thumbnail-fallback.jpg"; const VIDEO_EVENT_KIND = 30078; -const HEX64_REGEX = /^[0-9a-f]{64}$/i; + const RELAY_UI_BATCH_DELAY_MS = 250; /** * Simple IntersectionObserver-based lazy loader for images (or videos). diff --git a/js/directMessagesStore.js b/js/directMessagesStore.js index c7c1d20e..1d2d862f 100644 --- a/js/directMessagesStore.js +++ b/js/directMessagesStore.js @@ -1,4 +1,5 @@ import { userLogger } from "./utils/logger.js"; +import { HEX64_REGEX } from "./utils/hex.js"; const DB_NAME = "bitvidSettings"; const DB_VERSION = 1; @@ -6,7 +7,7 @@ const STORE_NAME = "kv"; const KEY_PREFIX = "dmSnapshot:"; const LOCALSTORAGE_PREFIX = "bitvid:dmSnapshot:"; const PREVIEW_MAX_LENGTH = 160; -const HEX64_REGEX = /^[0-9a-f]{64}$/i; + function isIndexedDbAvailable() { try { diff --git a/js/dmDecryptor.js b/js/dmDecryptor.js index d8096232..3001a3bb 100644 --- a/js/dmDecryptor.js +++ b/js/dmDecryptor.js @@ -1,8 +1,9 @@ // js/dmDecryptor.js import { normalizeActorKey } from "./nostr/watchHistory.js"; +import { HEX64_REGEX } from "./utils/hex.js"; + -const HEX64_REGEX = /^[0-9a-f]{64}$/; const SUPPORTED_KINDS = new Set([4, 1059]); diff --git a/js/embed.js b/js/embed.js index ed785957..a6f76577 100644 --- a/js/embed.js +++ b/js/embed.js @@ -6,6 +6,7 @@ import { resolveVideoPointer } from "./utils/videoPointer.js"; import { devLogger, userLogger } from "./utils/logger.js"; import { nostrToolsReady } from "./nostrToolsBootstrap.js"; import { THEME_ACCENT_OVERRIDES } from "../config/instance-config.js"; +import { HEX64_REGEX } from "./utils/hex.js"; // Set accent color from instance config try { @@ -51,7 +52,7 @@ const diagPromise = embedDebugEnabled const POINTER_PARAM = "pointer"; const PLAYBACK_PARAM = "playback"; -const HEX64_REGEX = /^[0-9a-f]{64}$/i; + const statusEl = document.getElementById("embedStatus"); const videoEl = document.getElementById("embedVideo"); diff --git a/js/nostr/adapters/nsecAdapter.js b/js/nostr/adapters/nsecAdapter.js index 5bb94cc2..b8dca77b 100644 --- a/js/nostr/adapters/nsecAdapter.js +++ b/js/nostr/adapters/nsecAdapter.js @@ -4,8 +4,9 @@ import { signEventWithPrivateKey } from "../publishHelpers.js"; import { createPrivateKeyCipherClosures } from "../signerHelpers.js"; import { ensureNostrTools, getCachedNostrTools } from "../toolkit.js"; import { normalizeActorKey } from "../watchHistory.js"; +import { HEX64_REGEX } from "../../utils/hex.js"; + -const HEX64_REGEX = /^[0-9a-f]{64}$/i; function normalizePrivateKey(privateKey) { if (typeof privateKey !== "string") { diff --git a/js/nostr/client.js b/js/nostr/client.js index 6dc72632..b83a8e52 100644 --- a/js/nostr/client.js +++ b/js/nostr/client.js @@ -157,8 +157,8 @@ import { readStoredSessionActorEntry, isSessionActor, } from "./sessionActor.js"; +import { HEX64_REGEX } from "../utils/hex.js"; import { - HEX64_REGEX, NIP46_RPC_KIND, NIP46_SESSION_STORAGE_KEY, NIP46_PUBLISH_TIMEOUT_MS, diff --git a/js/nostr/dmDecryptWorker.js b/js/nostr/dmDecryptWorker.js index 73603d93..3ce459ae 100644 --- a/js/nostr/dmDecryptWorker.js +++ b/js/nostr/dmDecryptWorker.js @@ -1,8 +1,9 @@ import { ensureNostrTools, getCachedNostrTools } from "./toolkit.js"; import { devLogger } from "../utils/logger.js"; +import { HEX64_REGEX } from "../utils/hex.js"; const workerScope = typeof self !== "undefined" ? self : null; -const HEX64_REGEX = /^[0-9a-f]{64}$/i; + const postResponse = (payload) => { if (!workerScope || typeof workerScope.postMessage !== "function") { diff --git a/js/nostr/nip46Client.js b/js/nostr/nip46Client.js index 2931266c..b2467c53 100644 --- a/js/nostr/nip46Client.js +++ b/js/nostr/nip46Client.js @@ -26,8 +26,7 @@ import { } from "../nostrPublish.js"; import { devLogger, userLogger } from "../utils/logger.js"; import { Nip46RequestQueue, NIP46_PRIORITY } from "./nip46Queue.js"; - -export const HEX64_REGEX = /^[0-9a-f]{64}$/i; +import { HEX64_REGEX } from "../utils/hex.js"; export const NIP46_RPC_KIND = 24_133; export const NIP46_SESSION_STORAGE_KEY = "bitvid:nip46:session:v1"; diff --git a/js/nostr/publishHelpers.js b/js/nostr/publishHelpers.js index 429fcd10..ffc1f782 100644 --- a/js/nostr/publishHelpers.js +++ b/js/nostr/publishHelpers.js @@ -20,12 +20,13 @@ import { DEFAULT_NIP07_PERMISSION_METHODS } from "./nip07Permissions.js"; import { devLogger, userLogger } from "../utils/logger.js"; import { logRebroadcastCountFailure } from "./countDiagnostics.js"; import { queueSignEvent } from "./signRequestQueue.js"; +import { HEX64_REGEX } from "../utils/hex.js"; const REBROADCAST_GUARD_PREFIX = "bitvid:rebroadcast:v1"; const rebroadcastAttemptMemory = new Map(); const HEX_PRIVATE_KEY_REGEX = /^[0-9a-f]{64}$/i; -const HEX64_REGEX = /^[0-9a-f]{64}$/i; + function normalizeSha256TagValue(value) { if (value === undefined || value === null) { diff --git a/js/nostr/signerHelpers.js b/js/nostr/signerHelpers.js index 51857eff..21fd6479 100644 --- a/js/nostr/signerHelpers.js +++ b/js/nostr/signerHelpers.js @@ -1,7 +1,7 @@ // js/nostr/signerHelpers.js import { devLogger } from "../utils/logger.js"; -import { HEX64_REGEX } from "./nip46Client.js"; +import { HEX64_REGEX } from "../utils/hex.js"; import { ensureNostrTools, getCachedNostrTools } from "./toolkit.js"; import { normalizeActorKey } from "./watchHistory.js"; diff --git a/js/nwcSettings.js b/js/nwcSettings.js index 46dbface..7074a9ba 100644 --- a/js/nwcSettings.js +++ b/js/nwcSettings.js @@ -1,10 +1,11 @@ import { userLogger } from "./utils/logger.js"; +import { HEX64_REGEX } from "./utils/hex.js"; const DB_NAME = "bitvidSettings"; const DB_VERSION = 1; const STORE_NAME = "kv"; const KEY_PREFIX = "nwcSettings:"; const LOCALSTORAGE_PREFIX = "bitvid:nwcSettings:"; -const HEX64_REGEX = /^[0-9a-f]{64}$/i; + const MIN_DEFAULT_ZAP = 0; const MAX_DEFAULT_ZAP = 100000000; diff --git a/js/payments/nwcClient.js b/js/payments/nwcClient.js index 3697665d..5a616cbd 100644 --- a/js/payments/nwcClient.js +++ b/js/payments/nwcClient.js @@ -4,8 +4,9 @@ import { nostrToolsReady } from "../nostrToolsBootstrap.js"; import { signEventWithPrivateKey } from "../nostr/publishHelpers.js"; import { userLogger } from "../utils/logger.js"; import { isZapAllowanceExhaustedError } from "./zapSharedState.js"; +import { HEX64_REGEX } from "../utils/hex.js"; + -const HEX64_REGEX = /^[0-9a-f]{64}$/i; const URI_SCHEMES = [ "nostr+walletconnect://", "walletconnect://", diff --git a/js/payments/platformAddress.js b/js/payments/platformAddress.js index d2ff6f53..5399ac2f 100644 --- a/js/payments/platformAddress.js +++ b/js/payments/platformAddress.js @@ -5,8 +5,9 @@ import { nostrClient } from "../nostrClientFacade.js"; import { setProfileCacheEntry } from "../state/cache.js"; import { nostrToolsReady } from "../nostrToolsBootstrap.js"; import { userLogger } from "../utils/logger.js"; +import { HEX64_REGEX } from "../utils/hex.js"; + -const HEX64_REGEX = /^[0-9a-f]{64}$/i; const CACHE_TTL_MS = 10 * 60 * 1000; let cachedAddress = null; diff --git a/js/payments/zapSplit.js b/js/payments/zapSplit.js index 8363c618..4fa27a5c 100644 --- a/js/payments/zapSplit.js +++ b/js/payments/zapSplit.js @@ -20,8 +20,9 @@ import { parsePercentValue, resolvePlatformFeePercent, } from "./platformFee.js"; +import { HEX64_REGEX } from "../utils/hex.js"; + -const HEX64_REGEX = /^[0-9a-f]{64}$/i; const ZAP_KIND = 9734; const DEFAULT_DEPS = Object.freeze({ lnurl: Object.freeze({ diff --git a/js/services/authService.js b/js/services/authService.js index 602a2ed4..cb84b23b 100644 --- a/js/services/authService.js +++ b/js/services/authService.js @@ -27,6 +27,7 @@ import getDefaultAuthProvider, { providers as defaultAuthProviders, } from "./authProviders/index.js"; import { fetchProfileMetadata } from "./profileMetadataService.js"; +import { HEX64_REGEX } from "../utils/hex.js"; class SimpleEventEmitter { constructor(logger = null) { @@ -69,7 +70,7 @@ class SimpleEventEmitter { } } -const HEX64_REGEX = /^[0-9a-f]{64}$/i; + const FALLBACK_PROFILE = { name: "Unknown", picture: "assets/svg/default-profile.svg", diff --git a/js/services/hashtagPreferencesService.js b/js/services/hashtagPreferencesService.js index ab2a1574..438cd33a 100644 --- a/js/services/hashtagPreferencesService.js +++ b/js/services/hashtagPreferencesService.js @@ -30,10 +30,11 @@ import { getLastSuccessfulScheme, setLastSuccessfulScheme, } from "../nostr/decryptionSchemeCache.js"; +import { HEX64_REGEX } from "../utils/hex.js"; const LOG_PREFIX = "[HashtagPreferences]"; const HASHTAG_IDENTIFIER = "bitvid:tag-preferences"; -const HEX64_REGEX = /^[0-9a-f]{64}$/i; + const DEFAULT_VERSION = 1; const DECRYPT_TIMEOUT_MS = 20000; // PERF: Reduced from 10s to 3s for faster recovery during login. diff --git a/js/services/profileMetadataService.js b/js/services/profileMetadataService.js index 84b11405..1b2e991b 100644 --- a/js/services/profileMetadataService.js +++ b/js/services/profileMetadataService.js @@ -1,9 +1,10 @@ import { nostrClient } from "../nostrClientFacade.js"; import { devLogger } from "../utils/logger.js"; import { relaySubscriptionService } from "./relaySubscriptionService.js"; +import { HEX64_REGEX } from "../utils/hex.js"; const DEFAULT_PROFILE_IMAGE = "assets/svg/default-profile.svg"; -const HEX64_REGEX = /^[0-9a-f]{64}$/i; + const inFlight = new Map(); function normalizePubkey(pubkey) { diff --git a/js/state/cache.js b/js/state/cache.js index 7fb2992a..8adf23da 100644 --- a/js/state/cache.js +++ b/js/state/cache.js @@ -27,7 +27,7 @@ const URL_HEALTH_TIMEOUT_RETRY_MS = 5 * 60 * 1000; // 5 minutes export const URL_PROBE_TIMEOUT_MS = 8 * 1000; // 8 seconds const URL_PROBE_TIMEOUT_RETRY_MS = 15 * 1000; // 15 seconds -const HEX64_REGEX = /^[0-9a-f]{64}$/i; + const MODERATION_OVERRIDE_STORAGE_KEY = "bitvid:moderationOverrides:v2"; const LEGACY_MODERATION_OVERRIDE_STORAGE_KEY = "bitvid:moderationOverrides:v1"; @@ -839,6 +839,7 @@ export function persistProfileCacheToStorage() { } import { profileCache as unifiedProfileCache } from "./profileCache.js"; +import { HEX64_REGEX } from "../utils/hex.js"; export function getProfileCacheEntry(pubkey) { const profile = unifiedProfileCache.getProfile(pubkey); diff --git a/js/ui/components/VideoCard.js b/js/ui/components/VideoCard.js index 342184ea..d5bddccc 100644 --- a/js/ui/components/VideoCard.js +++ b/js/ui/components/VideoCard.js @@ -12,10 +12,11 @@ import { normalizeVideoModerationContext, } from "../moderationUiHelpers.js"; import { buildModerationBadgeText } from "../moderationCopy.js"; +import { HEX64_REGEX } from "../../utils/hex.js"; const SVG_NAMESPACE = "http://www.w3.org/2000/svg"; const DEFAULT_PROFILE_AVATAR = "assets/svg/default-profile.svg"; -const HEX64_REGEX = /^[0-9a-f]{64}$/i; + export class VideoCard { constructor({ diff --git a/js/ui/components/VideoModal.js b/js/ui/components/VideoModal.js index 722e535f..62ee9f6f 100644 --- a/js/ui/components/VideoModal.js +++ b/js/ui/components/VideoModal.js @@ -46,8 +46,9 @@ import { isLinkPreviewDomainAllowed, subscribeToLinkPreviewSettings, } from "../../utils/linkPreviewSettings.js"; +import { HEX64_REGEX } from "../../utils/hex.js"; + -const HEX64_REGEX = /^[0-9a-f]{64}$/i; const SIMILAR_CONTENT_LIMIT = 10; export class VideoModal { diff --git a/js/utils/hex.js b/js/utils/hex.js index 367f78bd..e0cfca22 100644 --- a/js/utils/hex.js +++ b/js/utils/hex.js @@ -1,3 +1,5 @@ +export const HEX64_REGEX = /^[0-9a-f]{64}$/i; + export function normalizeHexString(value) { if (typeof value !== "string") { return ""; diff --git a/js/utils/profileBatchFetcher.js b/js/utils/profileBatchFetcher.js index 365f0fd1..1c3b20e1 100644 --- a/js/utils/profileBatchFetcher.js +++ b/js/utils/profileBatchFetcher.js @@ -3,9 +3,10 @@ import { nostrClient } from "../nostrClientFacade.js"; import { devLogger } from "./logger.js"; import { fetchProfileMetadataBatch } from "../services/profileMetadataService.js"; +import { HEX64_REGEX } from "./hex.js"; const DEFAULT_PROFILE_IMAGE = "assets/svg/default-profile.svg"; -const HEX64_REGEX = /^[0-9a-f]{64}$/i; + export async function batchFetchProfilesFromRelays({ authorSet, diff --git a/tests/app/is-user-logged-in.test.mjs b/tests/app/is-user-logged-in.test.mjs index 84d503d6..57779a5f 100644 --- a/tests/app/is-user-logged-in.test.mjs +++ b/tests/app/is-user-logged-in.test.mjs @@ -3,8 +3,9 @@ import assert from "node:assert/strict"; import { Application } from "../../js/app.js"; import { nostrClient } from "../../js/nostrClientFacade.js"; +import { HEX64_REGEX } from "../../js/utils/hex.js"; + -const HEX64_REGEX = /^[0-9a-f]{64}$/i; function createTestApp(pubkey) { const app = { From 955398d338a38cc23b3f4b099f4dcaba7b686ab8 Mon Sep 17 00:00:00 2001 From: bitvid-agent Date: Sat, 7 Feb 2026 21:56:02 +0000 Subject: [PATCH 2/2] fix(ai): formatting (agent) suggested --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 59b39571..7441c5a9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -161,7 +161,7 @@ To set up the project locally: npm run telemetry:aggregate ``` -4. **Format & Lint**: +5. **Format & Lint**: ```bash npm run format