Replaces the sequential loop in `forceRefreshAllProfiles` with `batchFetchProfiles` to reduce network requests.
Updates `batchFetchProfilesFromRelays` to support `forceRefresh`, ensuring fresh data is requested while maintaining optimistic UI updates.
Adds unit tests for `forceRefresh` behavior.
Co-authored-by: PR0M3TH3AN <[email protected]>
- Added `tests/utils/domUtils.test.mjs` to test `escapeHTML` and `removeTrackingScripts`.
- Verified tests pass with `node:test` and JSDOM.
Co-authored-by: PR0M3TH3AN <[email protected]>
- Validated `pendingAuthUrl` protocol to be `http:` or `https:` in `js/ui/loginModalController.js`.
- Logged warning if unsafe URL is encountered.
Signed-off-by: Jules <[email protected]>
Co-authored-by: PR0M3TH3AN <[email protected]>
Extracted the complex parsing, validation, and migration logic for saved profiles into a new helper function `processSavedProfilesPayload`. This reduces the complexity of `loadSavedProfilesFromStorage` and improves readability.
Functionality is preserved, including handling of legacy formats, NIP-07 auth types, and active profile normalization.
Verified with targeted tests:
- tests/state/cache-saved-profiles.test.mjs
- tests/state/cache.test.mjs
Co-authored-by: PR0M3TH3AN <[email protected]>
Introduced FEED_TYPES constants in js/constants.js and updated js/app/authSessionCoordinator.js, js/hashChangeHandler.js, js/viewManager.js, and js/app/feedCoordinator.js to use them. This improves maintainability and reduces the risk of typos in feed view names.
Co-authored-by: PR0M3TH3AN <[email protected]>
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 <[email protected]>
Co-authored-by: PR0M3TH3AN <[email protected]>
Removed `export` from `NIP46_SESSION_STORAGE_KEY`, `NIP46_PUBLISH_TIMEOUT_MS`, `NIP46_RESPONSE_TIMEOUT_MS`, `NIP46_SIGN_EVENT_TIMEOUT_MS`, and `NIP46_MAX_RETRIES` in `js/nostr/nip46Client.js` as they are only used internally.
Updated `js/nostr/client.js` to remove unused imports of these constants.
Verified that `NIP46_HANDSHAKE_TIMEOUT_MS` and `NIP46_AUTH_CHALLENGE_MAX_ATTEMPTS` are used in `js/nostr/client.js` and thus remain exported.
Co-authored-by: PR0M3TH3AN <[email protected]>
Removes the unused `MAX_WALLET_DEFAULT_ZAP` import from `js/app.js` to improve code health and reduce confusion. This variable was imported from `config.js` but never used within `app.js`.
Verification:
- Confirmed `MAX_WALLET_DEFAULT_ZAP` is not present in `js/app.js`.
- Ran `tests/app/is-user-logged-in.test.mjs` to ensure `js/app.js` still loads and functions correctly.
Co-authored-by: PR0M3TH3AN <[email protected]>
Implements a load testing script for Nostr relays that simulates multiple clients, generates mixed event traffic (View/Video), and measures performance metrics including latency, throughput, and CPU usage. It also includes strict safety guardrails to prevent accidental load testing against public relays.
Signed-off-by: Jules <[email protected]>
Co-authored-by: PR0M3TH3AN <[email protected]>
- Implements an Inverted Index to reduce redundant similarity checks.
- Replaces O(N) array splice with O(1) Map deletion for candidate tracking.
- Reduces runtime from ~3.5s to ~0.9s for 5000 items (3.9x speedup).
Co-authored-by: PR0M3TH3AN <[email protected]>
Three performance bottlenecks were causing slow list loading after NIP-07 login:
1. Each list service (blocks, subscriptions, hashtag preferences) maintained
its own isolated decryptionSuccessCache. When blocks decrypted with nip44_v2,
subscriptions and hashtag preferences had no way to know — they each had to
independently probe all schemes through the NIP-07 extension queue, tripling
the number of extension calls during the critical login path.
2. List loading was gated on both relaysReadyPromise AND permissionPromise in
the coordinator. Since the NIP-07 extension already grants decrypt permissions
during loginWithExtension(), the redundant pre-grant was adding 2-5 seconds
of unnecessary latency before any list fetching could begin.
3. The DECRYPT_RETRY_DELAY_MS was 10 seconds across all services. When a decrypt
attempt failed transiently (extension still initializing), the retry waited
far too long before trying again.
Changes:
- Create shared decryptionSchemeCache module used by all three list services
- Add fast-path: when shared cache knows the correct scheme, try ONLY that
scheme before falling back to parallel Promise.any() probe
- Remove permissionPromise from the list-loading gate in authSessionCoordinator
- Reduce DECRYPT_RETRY_DELAY_MS from 10s to 3s in all three services
- Clear shared cache on logout
https://claude.ai/code/session_013QrGMnxtMTsGTPqaP35jMj