Commit Graph
73 Commits
Author SHA1 Message Date
google-labs-jules[bot]andPR0M3TH3AN 0ae813ea66 perf(feed): optimize moderation stage with batch author lookups (perf-optimization-agent)
- Implement `getModerationInfoForAuthors` in `ModerationService` for batching.
- Extract utility functions to `js/services/moderationUtils.js` to reduce `ModerationService` size.
- Update `createModerationStage` to use batch lookup, reducing sequential overhead.
- Benchmarks show ~50% improvement (454ms -> 227ms) for 5000 items.
- All unit tests pass.
- Task log: `docs/agents/task-logs/weekly/2026-02-22_01-25-01_perf-optimization-agent_completed.md`

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-22 01:26:39 +00:00
google-labs-jules[bot]andPR0M3TH3AN e62cb15c0e perf: parallelize timestamp resolution in feed engine
Replaces sequential await loop with Promise.any to resolve video timestamps in parallel.
This significantly reduces latency when multiple resolvers are present, especially if the first one is slow.

- Uses Promise.any to take the first valid finite timestamp.
- Wraps resolvers to reject on invalid values.
- Preserves error logging for genuine resolver errors.
- Benchmarks showed improvement from ~100ms to ~11ms in simulated slow scenarios.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-11 12:38:20 +00:00
google-labs-jules[bot]andPR0M3TH3AN 6f49a05302 feat(perf): Optimize feed tag extraction with caching
- Extracted `getVideoTags` to `js/feedEngine/utils.js` with `WeakMap` caching.
- Updated `js/feedEngine/stages.js` and `js/feedEngine/kidsScoring.js` to use the cached utility.
- Removed redundant `collectVideoTags` and `normalizeTagSetFromVideo` functions.
- Added `benchmarks/feed_tags.mjs` to measure performance (approx 25x speedup in tight loops).
- Updated `hasDisinterestedTag` in `utils.js` to use the new utility.

This reduces object allocation and repeated string normalization during feed processing.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-10 19:44:30 +00:00
google-labs-jules[bot]andPR0M3TH3AN f954bf3d89 Optimize feed engine normalization with array marking
- Introduced `NORMALIZED_ARRAY_MARKER` in `js/feedEngine/utils.js` to tag arrays that are already normalized.
- Updated `normalizeItems` in `js/feedEngine/engine.js` to skip O(N) verification if the input array is marked.
- Updated built-in stages and sorters to mark their output arrays using `markAsNormalized` when they safely construct new arrays from normalized inputs.
- This avoids redundant O(N) scans after each stage, improving pipeline performance by ~10% end-to-end and eliminating overhead for trusted stages.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-10 17:00:52 +00:00
google-labs-jules[bot]andPR0M3TH3AN 2275aa3bb1 Optimize feed scoring by caching normalized tag sets
- Introduce `videoTagCache` (WeakMap) in `js/feedEngine/kidsScoring.js`
- Cache result of `normalizeTagSetFromVideo` to avoid re-computation
- Improved benchmark performance by ~35%

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-10 04:59:46 +00:00
Claude 29215d9b5e Speed up Nostr login and fix list sync, storage unlock, and feed registration
- Remove redundant double signer readiness gate evaluation that added 5-10s
  to the login path (authSessionCoordinator)
- Reduce decryption timeouts (10s→6s per scheme, 3s→1.5s retry delay,
  8s→5s NIP-07 no-prompt, 45s→25s overall ensureLoaded) for faster scheme
  fallback during list sync
- Fix storage tab unlock: remove overly strict capabilities check that
  blocked lazy-injecting NIP-07 extensions, and add auto-unlock attempt
  when profile modal opens with an active signer
- Fix subscription/hashtag decryption: always resolve signer for background
  refreshes (was previously gated behind allowPermissionPrompt), and always
  check window.nostr as fallback decryptor regardless of prompt mode
- Fix capabilities check in subscription decryption: use method existence
  instead of dynamic capabilities getter that returns false during lazy
  extension injection
- Wrap Promise.any decryptor calls in Promise.resolve().then() to catch
  synchronous throws from NIP-07 adapter methods when extension modules
  haven't loaded yet
- Make watch-history feed registration race-safe with pre-check and
  try/catch for concurrent registration attempts
- Improve NIP-07 extension detection with DOMContentLoaded listener for
  faster detection of extensions that inject during page load

https://claude.ai/code/session_0174XTB5ADJ9cMBSucqL9Wer
2026-02-09 00:18:43 +00:00
thePR0M3TH3AN fd3f9e723a Split subscriptions/hashtag readiness and expose unavailable preference states 2026-02-08 14:10:39 -05:00
google-labs-jules[bot]andPR0M3TH3AN 7c1f3c9ada perf: Optimize chronological sorter hook resolution
Hoisted the timestamp hook resolution out of the inner loop in `createChronologicalSorter`.
This avoids allocating an array of candidate functions for every comparison during sorting (O(N log N)).
Benchmark shows a ~27% speedup (38ms -> 27ms for 100k items).

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 16:55:27 +00:00
google-labs-jules[bot]andPR0M3TH3AN 96dea42692 Optimize object allocation in kids scoring loop
- Replaced array allocation and loop with unrolled scalar comparisons in `kidsScorerStage`.
- Added unit tests and benchmark.
- Measured ~12% performance improvement (282ms -> 249ms for 200k items).

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 03:41:50 +00:00
google-labs-jules[bot]andPR0M3TH3AN 2320887665 perf: optimize createExploreDiversitySorter with inverted index
- 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]>
2026-02-07 16:55:05 +00:00
Claude 3a55e1bf03 fix: resolve coordinator refactoring regressions breaking DM, lists, and feed pipeline
- Remove undefined hashtagPreferencesPromise reference in handleAuthLogin
  that caused the feed sync Promise.allSettled to silently fail, preventing
  proper list/profile synchronization before grid refresh
- Add missing getModerationSettings and getActiveProfilePubkey dependency
  injection to authSessionCoordinator, fixing crashes during logout
  moderation reset and profile switch pubkey resolution
- Parallelize NIP-07 permission request with relay readiness instead of
  gating list loading behind it; parallelize subscriptions and hashtag
  preference loading (independent of each other, only blocks must sequence)
- Add native run() alias to feedEngine so callers don't rely solely on
  the applicationBootstrap compatibility shim
- Remove redundant refreshVisibleModerationUi call from renderVideoList
  that re-decorated every video immediately after decoration
- Avoid re-normalizing moderation settings on every getActiveModerationThresholds
  call when settings are already an object

https://claude.ai/code/session_01FCosieUXjEn95KtUeyGemY
2026-02-06 21:42:49 +00:00
google-labs-jules[bot]andPR0M3TH3AN 16458d1bc2 perf: Optimize explore diversity sorter
- Pre-calculate normalized vector norms to avoid O(N^2) recalculation.
- Pre-calculate normalized scores to avoid redundant property access and normalization.
- Combine selection loops to reduce iteration overhead.
- Modify cosineSimilarity to use dot product on normalized vectors.

Benchmark (1000 items): ~240ms -> ~152ms (~37% improvement).

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-06 16:49:55 +00:00
google-labs-jules[bot]andPR0M3TH3AN 6672be9281 Optimize feed engine normalization loop
Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-05 20:50:30 +00:00
google-labs-jules[bot]andPR0M3TH3AN 4c45555b26 Optimize explore diversity sorter to O(N^2)
- Replaced O(N^3) MMR algorithm with O(N^2) implementation
- Cached max similarity penalties to avoid redundant calculations
- Added benchmark script showing ~200x speedup for 1000 items

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-05 20:12:36 +00:00
google-labs-jules[bot]andPR0M3TH3AN 1846f865f5 Optimize feed engine normalization to reduce GC pressure
- Introduce `NORMALIZED_MARKER` Symbol to mark normalized items.
- Optimize `normalizeDto` to return existing object if marked.
- Optimize `normalizeItems` to scan for markers and return input array if all items are valid and marked, avoiding unnecessary array allocation and object re-creation.
- Preserve safety logic in `runFeed` (handle nulls and always call normalizer) while benefiting from internal optimization.

Benchmark results show ~9x speedup for "Same Instance" updates and ~5x speedup for "Copy Array" updates in the feed pipeline.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-05 19:43:09 +00:00
thePR0M3TH3AN a36ea40288 Add kids feed registration and sorter 2026-01-23 01:59:57 -05:00
thePR0M3TH3AN ed99db01ea Add kids feed scoring stage 2026-01-23 01:54:11 -05:00
thePR0M3TH3AN ba68c10950 Add kids audience filter stage 2026-01-23 01:50:12 -05:00
thePR0M3TH3AN 4abe9f3d1e Add disinterest tag filter stage 2026-01-22 19:10:27 -05:00
thePR0M3TH3AN c3aa42f39c Add explore feed pipeline 2026-01-22 19:04:50 -05:00
thePR0M3TH3AN 4eabdc3234 Add explore diversity sorter 2026-01-22 18:52:49 -05:00
thePR0M3TH3AN 67b7dc50f4 Add explore scoring stage factory 2026-01-22 18:13:49 -05:00
google-labs-jules[bot] 88fd378648 chore(ai): remove dead code (magnet.js and unused exports)
- Deleted `js/magnet.js` as it was a redundant wrapper for `js/magnetUtils.js`.
- Refactored `js/services/videoNotePayload.js`, `js/ui/components/EditModal.js`, and `js/nostr/nip71.js` to use `magnetUtils.js` and `magnetShared.js`.
- Updated `tests/magnet-utils.test.mjs` to remove tests for the deleted file.
- Removed unused exports `DEFAULT_FEED_CONFIG` and `DEFAULT_CONFIG_SCHEMA` from `js/feedEngine/engine.js` and `index.js`.
- Verified changes with unit tests.
2026-01-22 20:29:07 +00:00
thePR0M3TH3AN 8516382ece Update tag preference filtering 2026-01-18 14:05:47 -05:00
thePR0M3TH3AN 7a29a0b807 Consolidate tag preference filtering stage 2026-01-18 13:38:34 -05:00
thePR0M3TH3AN 0ac64867da Add shared hashtag normalization helper 2026-01-18 13:35:34 -05:00
thePR0M3TH3AN 3a3339a57a Add per-category trusted mute thresholds 2026-01-16 10:49:32 -05:00
google-labs-jules[bot] 8a61acb09c Add debug logging to trace subscription loading hang 2026-01-12 00:10:04 +00:00
google-labs-jules[bot] b07332395b Fix subscription feed hydration and infinite loading state 2026-01-08 19:24:10 +00:00
google-labs-jules[bot] 7d274bc331 feat: incorporate tag preferences into blacklist filter stage
- Implements `hasDisinterestedTag` helper in `js/feedEngine/utils.js` to check for disinterested tags in both raw Nostr tags and NIP-71 metadata.
- Updates `createBlacklistFilterStage` in `js/feedEngine/stages.js` to filter out videos matching `context.runtime.tagPreferences` disinterests.
- Ensures existing blacklist logic remains undisturbed.
- Verified with new unit test `tests/feed-engine-tag-pref.test.mjs` and existing feed engine tests.
2026-01-08 00:52:57 +00:00
google-labs-jules[bot] f2c87051ce feat: add profile hydration to watch history feed
This change introduces `createWatchHistoryProfileHydrationStage` to the
watch history feed pipeline. The stage resolves author profiles for
hydrated videos by:
1. Checking the global `getProfileCacheEntry` for cached profiles.
2. Batching missing profiles into a single Kind 0 relay request.
3. Updating the global cache (`setProfileCacheEntry`) with fetched data.
4. Attaching the resolved profile to `item.metadata.profile`.

This ensures that channel images populate correctly in the watch history
UI (both sidebar and profile modal).
2026-01-07 20:28:44 +00:00
google-labs-jules[bot] c322fcee14 fix(watch-history): add manual refresh and fix dynamic pulling
This commit addresses issues with the watch history not updating dynamically and adds a manual refresh mechanism.

Changes:
- Added a "Refresh" button to the watch history view in `views/history.html` and `js/historyView.js`.
- Updated `watchHistoryService.js` to accept a `forceRefresh` option in `loadLatest`, which bypasses the cache freshness check and triggers a relay fetch.
- Updated `js/feedEngine/watchHistoryFeed.js` to propagate the `forceRefresh` flag from the runtime context to the service.
- Added user feedback (toast messages and logs) for "Clear Local History" and "Republish Now" actions.
- Updated `tests/watch-history.test.mjs` to align with the new `fetchHistory` signature.
2026-01-07 14:05:21 +00:00
google-labs-jules[bot] f2f55830e8 fix: ensure watch history is sorted by most recent first
- Enforce descending month order in `js/nostr/watchHistory.js` by explicitly sorting keys before flattening buckets.
- Update `js/feedEngine/watchHistoryFeed.js` and `js/historyView.js` to use `video.created_at` as a fallback sort key when `watchedAt` is missing or equal.
- Verified logic with `tests/verify_sort.mjs`.
2026-01-07 00:28:39 +00:00
google-labs-jules[bot] 386ddea44a Enhance watch history hydration with relay hints and verbose logging
The watch history hydration process was sometimes failing to retrieve video metadata, resulting in "Untitled video" cards. This was primarily due to only querying the generic relay list and potentially missing content hosted on specific relays.

This commit improves the robustness of `createWatchHistoryHydrationStage` in `js/feedEngine/watchHistoryFeed.js` by:
1.  Collecting unique relay hints from the pointer objects (`item.pointer.relay`) of items needing hydration.
2.  Merging these hints with the user's `readRelays` (or fallback `relays`) list. This ensures that if a specific video is known to exist on a niche relay, that relay is queried during the metadata fetch.
3.  Replacing conditional debug logging with `devLogger.info` and `devLogger.warn` to provide detailed insights into the hydration process (item counts, selected relays, generated filters, and fetch results), aiding in future diagnosis.

These changes ensure the application attempts to fetch metadata from all relevant sources indicated by the history data itself.
2026-01-06 13:30:51 +00:00
google-labs-jules[bot] b03d96f041 Add verbose logging and fix relay selection for watch history hydration
The watch history hydration stage was failing silently when relay connections were unstable or misconfigured. This commit:
1. Replaces the conditional debug logger with `devLogger.info` and `devLogger.warn` to ensure visibility of critical hydration steps.
2. Adds detailed logging for item counts, missing ID/address lists, filter generation, and fetch results.
3. Updates the relay selection logic to prioritize `nostrClient.readRelays` over `nostrClient.relays`. This ensures that hydration attempts query the user's specific read-configured relays, which is crucial for fetching metadata when generic relays may be write-only or restricted.

These changes aid in diagnosing "Untitled video" issues and improve the robustness of the metadata fetch process.
2026-01-06 13:18:32 +00:00
google-labs-jules[bot] 93c88704e0 Fix watch history hydration by prioritizing readRelays
The `createWatchHistoryHydrationStage` in the feed engine was incorrectly relying solely on `nostrClient.relays` for network fetches. This could cause hydration failures if `relays` contained write-only servers or was otherwise restricted. This commit updates the logic to prioritize `nostrClient.readRelays` if available, falling back to `nostrClient.relays`. This ensures that hydration attempts query the correct relays configured for reading data.

Fixes an issue where watch history items would display as "Untitled video" due to failed metadata resolution.
2026-01-06 13:11:39 +00:00
google-labs-jules[bot] 7312fa4fa4 Fix watch history hydration using local cache and address support
Updated `createWatchHistoryHydrationStage` in `js/feedEngine/watchHistoryFeed.js` to first check `nostrClient.allEvents` for video data before querying relays. This ensures that recently watched videos (which are already in memory) are instantly hydrated in the watch history list, fixing the "Untitled video" issue.

Additionally, implemented robust support for hydrating address pointers (`type: 'a'`) by scanning the cache and constructing proper relay filters for missing items. This covers cases where history items reference videos by `kind:pubkey:d-tag` rather than ID.
2026-01-06 04:06:44 +00:00
google-labs-jules[bot] 914e0abc58 Fix watch history hydration for address pointers with colons
Updated `createWatchHistoryHydrationStage` in `js/feedEngine/watchHistoryFeed.js` to properly handle and hydrate watch history items that use address pointers (type 'a'), specifically fixing a bug where d-tags containing colons were being ignored.

Previously, only event ID pointers (type 'e') were being hydrated, and an initial fix for addresses failed for d-tags with colons. This change robustly parses address pointers, constructs appropriate filters, fetches the events, and correctly maps them back to the history items using a `normalizeAddressKey` utility that handles mixed-case pubkeys and complex d-tags.
2026-01-06 03:43:08 +00:00
google-labs-jules[bot] 1f54745840 Fix watch history hydration for address pointers
Updated `createWatchHistoryHydrationStage` in `js/feedEngine/watchHistoryFeed.js` to properly handle and hydrate watch history items that use address pointers (type 'a').

Previously, only event ID pointers (type 'e') were being hydrated, causing videos watched via address pointers to display as "Untitled video" with missing metadata. This change parses the address pointers, constructs appropriate filters (normalizing pubkeys to lowercase while preserving d-tag case), fetches the events, and correctly maps them back to the history items using a robust `normalizeAddressKey` utility.
2026-01-06 03:23:45 +00:00
google-labs-jules[bot] 5724ec4e1e Fix watch history hydration for address pointers
Updated `createWatchHistoryHydrationStage` in `js/feedEngine/watchHistoryFeed.js` to properly handle and hydrate watch history items that use address pointers (type 'a').

Previously, only event ID pointers (type 'e') were being hydrated, causing videos watched via address pointers to display as "Untitled video" with missing metadata. This change parses the address pointers, constructs appropriate filters, fetches the events, and correctly maps them back to the history items.
2026-01-06 02:51:18 +00:00
google-labs-jules[bot] 99c3f60a23 feat: implement video hydration stage for watch history feed
This introduces a new stage in the watch history feed pipeline that fetches missing video metadata from relays. Since watch history storage was optimized to store only event IDs, this hydration step ensures that the UI can display titles and thumbnails without requiring them to be persisted in the history payload itself.

- Implemented `createWatchHistoryHydrationStage` in `js/feedEngine/watchHistoryFeed.js`.
- Integrated `convertEventToVideo` to transform fetched events into usable video objects.
- Added a comprehensive integration test in `tests/watch-history.test.mjs` verifying the full flow from ID-only storage to hydrated feed items.
2026-01-05 20:22:34 +00:00
google-labs-jules[bot] 4c7230f540 Remove metadata storage and handling from watch history
Removes the metadata argument from `WatchHistoryService.publishView` and cleans up the associated caching and resolution logic in `watchHistory.js` and `watchHistoryFeed.js`. Deletes `js/watchHistoryMetadata.js` as it is no longer used.

This simplification ensures watch history strictly manages pointers and timestamps, leaving metadata resolution to higher-level consumers. It also reduces the payload size and complexity of persisted history records.

Tests have been updated to reflect the API changes.
2026-01-05 16:58:59 +00:00
thePR0M3TH3AN e9ce494ccd Remove watch history metadata caching 2026-01-03 09:11:26 -05:00
thePR0M3TH3AN 9dfe7ef20e Fix viewer mute blur regression and update modal overrides 2025-10-26 16:06:40 -04:00
thePR0M3TH3AN b744524521 Hydrate feed timestamps before sorting 2025-10-26 12:05:03 -04:00
thePR0M3TH3AN 89de704336 Use original publish timestamp when sorting feeds 2025-10-26 11:51:49 -04:00
thePR0M3TH3AN 010439998e Sort recent feed by original posting time 2025-10-26 11:34:36 -04:00
thePR0M3TH3AN 91404af8ad Make moderation thresholds resolve at runtime 2025-10-26 10:19:34 -04:00
thePR0M3TH3AN ad01cf852f Propagate tag preferences through feed runtimes 2025-10-25 17:38:31 -04:00
thePR0M3TH3AN 25f190aa90 Extend trusted mute moderation controls 2025-10-25 17:03:29 -04:00