fix: notifications are deduped in memory, not just in persistant storage#211
Open
LeosPrograms wants to merge 1 commit into
Open
fix: notifications are deduped in memory, not just in persistant storage#211LeosPrograms wants to merge 1 commit into
LeosPrograms wants to merge 1 commit into
Conversation
zippy
requested changes
May 13, 2026
Member
zippy
left a comment
There was a problem hiding this comment.
Some inline comments, and here are
Claude suggestions:
- O(n²) dedup with double-serialization per comparison. moss-store.ts:742-748: the filter + inner findIndex walks the feed twice per element, and getNotificationFeedEntryId calls encodeAndStringify (msgpack + base64) on each side of every comparison. And because the surrounding for (const notification of notifications) calls _notificationFeed.update once per notification, you compound this across the batch. A single-pass Map keeps the "newest wins" semantics and is O(n):
this._notificationFeed.update((feed) => {
const newEntry: MossNotification = { source, notification, sourceName: options.sourceName };
const seen = new Map<string, MossNotification>();
seen.set(getNotificationFeedEntryId(newEntry), newEntry);
for (const entry of feed) {
const id = getNotificationFeedEntryId(entry);
if (!seen.has(id)) seen.set(id, entry);
}
return [...seen.values()].sort((a, b) => b.notification.timestamp - a.notification.timestamp);
});
- Per-notification feed updates inside a batch loop. Since notifications can be an array, each one triggers its own _notificationFeed.update → re-sort → subscriber notification. For a batch of K notifications added against a feed of N entries, this is K separate sorts and K subscriber fan-outs. Could be hoisted to a single update that folds in all new entries at once. Not blocking, but cheap to fix while you're in there.
| } | ||
| // 1. Persist if requested (tools do this, foyer doesn't) | ||
| if (options.persist && source.type === 'applet') { | ||
| const unreadNotifications = storeAppletNotifications(notifications, source.appletId, true, this.persistedStore); |
Member
There was a problem hiding this comment.
This value is breaking CI because it's not read. and the value is pulled in the loop at line 722, should be re-using this value unless nothing was pulled by the guard here. Need to think this through better.
| ), | ||
| ); | ||
|
|
||
| return deduplicatedFeed.sort( |
Member
There was a problem hiding this comment.
inside loop this creates a n2 issue.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.