- Implements a priority queue for NIP-07 (browser extension) requests to allow critical tasks (blocklist/prefs decryption) to jump the line.
- Updates NIP-46 client and adapters to support priority overrides for encryption/decryption.
- Updates UserBlockListManager, SubscriptionsManager, and HashtagPreferencesService to request HIGH priority when decrypting data.
- Ensures strict serialization for NIP-07 to prevent extension errors while optimizing latency for critical data.
Co-authored-by: PR0M3TH3AN <[email protected]>
Introduced a request queue in `js/nostr/nip07Permissions.js` to serialize all interactions with the NIP-07 extension (`window.nostr`).
Updated `js/userBlocks.js`, `js/services/hashtagPreferencesService.js`, and `js/auth/signingAdapter.js` to wrap direct extension calls with `runNip07WithRetry`, ensuring they participate in the queue.
This resolves "message channel closed" errors and timeouts caused by concurrent requests flooding the extension during sync operations.
Co-authored-by: PR0M3TH3AN <[email protected]>
This commit updates `HashtagPreferencesService.decryptEvent` to register and utilize decryption methods from `window.nostr` (NIP-04 and NIP-44) as a fallback mechanism. This ensures that users without an active internal signer (e.g., read-only or extension-only users) can still decrypt their preferences if they have granted permission to the extension.
- Mirrors the decryption logic from `UserBlockListManager` (`js/userBlocks.js`).
- Adds logging for fallback attempts and failures.
- Preserves existing scheme selection logic (`determineDecryptionOrder`).
- Adds new test cases to `tests/hashtag-preferences.test.mjs` verifying fallback behavior when the active signer is missing or incapable.
Co-authored-by: PR0M3TH3AN <[email protected]>
- Updated `NostrClient.fetchListIncrementally` to prioritize user's NIP-65 read relays, cap concurrent requests, and temporarily mark failing relays as unreachable.
- Added `markRelayUnreachable` to `NostrClient` for temporary relay exclusion.
- Updated `SubscriptionsManager`, `HashtagPreferencesService`, and `UserBlockListManager` to use `relayManager.getReadRelayUrls()` for selecting relays, ensuring consistency with user preferences.
- Added structured logging for relay selection in `fetchListIncrementally`.
- Updated unit tests to mock `relayManager` behavior correctly.
Co-authored-by: PR0M3TH3AN <[email protected]>
- Reduced `fetchListIncrementally` timeout to 4000ms to fail faster on bad relays.
- Added 15s timeout to decryption calls in `HashtagPreferencesService`, `UserBlockListManager`, and `SubscriptionsManager` to prevent infinite hangs.
- Added handling for "message channel closed" error in `nip07Adapter` with a backoff delay to allow extension recovery.
- Prioritized preserving cached data on decryption failure instead of resetting to empty state.
Co-authored-by: PR0M3TH3AN <[email protected]>
- Wrapped NIP-07 adapter extension calls in `retryNip07Call` to handle transient failures and timeouts robustly.
- Updated `HashtagPreferencesService` to autosave changes to relays immediately on modification.
- Added race condition protection in `HashtagPreferencesService.load` to prevent overwriting optimistic local updates with stale relay data.
Co-authored-by: PR0M3TH3AN <[email protected]>
- Update `fetchListIncrementally` in `js/nostr/client.js` to throw an error if all relays fail, preventing empty returns from being interpreted as data loss.
- Update `HashtagPreferencesService`, `UserBlockListManager`, and `SubscriptionsManager` to handle fetch errors gracefully without wiping local state.
- Update `js/nostr/nip07Permissions.js` to use a short timeout (3s) for experimental permission requests, fixing "clunky" login issues while preserving user interaction time for standard login.
- Remove `try/catch` in `adminListStore.js` fetch logic to allow error propagation to the fallback cache logic.
Co-authored-by: PR0M3TH3AN <[email protected]>
- Updated `NostrClient.fetchListIncrementally` to accept a `since` override.
- Updated `HashtagPreferencesService.load` to pass `since` based on local cache timestamp.
- Ensures preferences are refreshed if local state is stale or missing, overriding potentially incorrect `SyncMetadataStore` state.
- Added regression tests for `fetchListIncrementally` since parameter logic.
Co-authored-by: PR0M3TH3AN <[email protected]>
- Implemented optimistic UI updates for the channel subscribe button to improve responsiveness.
- Fixed a race condition in `js/subscriptions.js` and `js/services/hashtagPreferencesService.js` where lists were wiped on refresh due to `profileCache.activePubkey` not being initialized in time. Now using `profileCache.getProfileData(pubkey, ...)` to ensure the correct cache entry is loaded.
- Validated with targeted unit tests.
Co-authored-by: PR0M3TH3AN <[email protected]>
When a user logs in, `profileCache` emits a `profileChanged` event. Previously, `HashtagPreferencesService` only reset its state on this event, failing to fetch the new user's preferences. This commit updates the subscription handler to call `load(pubkey)` when a new profile is set, ensuring interests and disinterests are reliably synchronized.
- fix `TypeError: Assignment to constant variable` in `HashtagPreferencesService.load` by changing `const` to `let` for `wasLoadedForUser`.
- Prevent existing cached preferences from being wiped when remote decryption fails.
- Migrated Kind 0 profile metadata storage to unified `profileCache.js` with partitioning and persistence.
- Added `defaultDTag` for hashtag preferences in `cachePolicies.js` to ensure consistent key resolution.
- Updated `hashtagPreferencesService.js` to use `profileCache` and implemented legacy data migration.
- Added `handleEvent` to `NostrClient` to centrally ingest Kind 0 events into the cache.
- Updated `authService.js` and `cache.js` to delegate profile operations to the unified cache system.
- Added `PROFILE_METADATA` schema to `nostrEventSchemas.js`.
- Add `isSessionActor` helper to `js/nostr/sessionActor.js` to identify ephemeral keys.
- Update `js/nostr/viewEvents.js` to namespace view deduplication caches by `actorPubkey` to prevent data leakage between sessions.
- Block comment publishing for session actors in `js/nostr/commentEvents.js`.
- Block watch history list publishing for session actors in `js/nostr/client.js`.
- Block user block list publishing for session actors in `js/userBlocks.js`.
- Block hashtag preference publishing for session actors in `js/services/hashtagPreferencesService.js`.
- Add inline documentation clarifying variable sources.
- Updated `profileCache.js` to support clearing runtime memory on signer change.
- Updated `NostrClient` to trigger `clearSignerRuntime` on `setActiveSigner`.
- Updated list services (`subscriptions`, `userBlocks`, `hashtagPreferences`, `watchHistory`) to listen for `runtimeCleared` and reload data.
- Updated `NostrClient` sync metadata methods to default to the active profile pubkey.
- Added `partition-updated` event emission to `profileCache`.
Implements a `SyncMetadataStore` to persist last-seen timestamps for replaceable lists (Kind 10000, 30000, 30002, 30015).
Adds `fetchListIncrementally` helper to `NostrClient` which performs per-relay `since` queries.
Updates `SubscriptionsManager`, `UserBlockListManager`, `HashtagPreferencesService`, and `adminListStore` to utilize incremental fetching.
Prevents local cache wipes when incremental fetches return empty results (indicating "no updates").
This commit updates `HashtagPreferencesService.load` to handle transient empty responses from relays more robustly.
- It prevents `reset()` if `wasLoadedForUser` is true and the fetch returns empty, ensuring existing data isn't wiped during connectivity issues or relay switches.
- It adds a staleness check to ignore incoming events that are older than the currently loaded data, protecting against out-of-sync relays returning obsolete preferences.
This addresses the issue where hashtag interests would disappear ("turn gray") or revert to older states shortly after login when video grid filters were applied.
Prevents `HashtagPreferencesService` from aggressively resetting local state to empty when a load attempt fails due to transient issues (like empty relay lists or network errors) if valid data is already loaded for the current user. This fixes a race condition where tags would briefly load correctly and then turn gray/disappear during application initialization.
- Fix circular dependency in `js/adminListStore.js` by importing from `js/nostrClientRegistry.js`.
- Update `js/services/hashtagPreferencesService.js` to include legacy kind 30005 in filters.
- Fix JSDOM mocking in `tests/modal-accessibility.test.mjs` (navigator getter) and `UploadModal` selectors.
- Add `getRoot()` to `js/ui/components/UploadModal.js` for API consistency.
- Update `tests/magnet-utils.test.mjs` expectations to reflect removed default tracker.
- Mock `ensureActiveSignerForPubkey` in `tests/moderation/submit-report.test.mjs`.
- Fix mock loader path in `tests/moderation/trust-seeds.test.mjs` to target `trustBootstrap.js`.
- Fix duplicate pointer tags in `js/nostrEventSchemas.js`'s `buildCommentEvent`.
- Update `tests/nostr/comment-events.test.mjs` and `tests/comment-event-builder.test.mjs` to match current code behavior (legacy kinds, unique tags).