Merge pull request #1957 from PR0M3TH3AN/codex/identify-cache-modules-for-profiles-and-dms

Merge cached profile fields and stabilize DM cache merging
This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2026-01-29 19:01:34 -05:00
commit 4d1c9f8ec9
2 files changed
+85 -47

No files matched your search

+54 -38
View File
@@ -176,6 +176,30 @@ function sanitizeSnapshotTimestamp(value) {
return floored;
}
function resolveDirectMessageCreatedAt(message) {
const createdAt = sanitizeSnapshotTimestamp(
message?.message?.created_at ??
message?.event?.created_at ??
message?.created_at ??
message?.timestamp,
);
if (createdAt) {
return createdAt;
}
return Math.floor(Date.now() / 1000);
}
function resolveDirectMessageSortValue(message) {
return sanitizeSnapshotTimestamp(
message?.created_at ??
message?.timestamp ??
message?.message?.created_at ??
message?.event?.created_at,
);
}
const SNAPSHOT_PREVIEW_LIMIT = 160;
function sanitizeSnapshotPreview(value) {
@@ -240,11 +264,7 @@ function resolvePreviewCacheKey(message) {
: typeof message?.remotePubkey === "string"
? message.remotePubkey.trim()
: "";
const timestamp = Number.isFinite(message?.timestamp)
? Math.floor(message.timestamp)
: Number.isFinite(message?.message?.created_at)
? Math.floor(message.message.created_at)
: 0;
const timestamp = resolveDirectMessageSortValue(message);
if (remote && timestamp) {
return `snapshot:${remote}:${timestamp}`;
@@ -401,11 +421,7 @@ function normalizeDirectMessageRecord(message, actorPubkey = "") {
receiverPubkey = senderPubkey === actor ? remote : actor;
}
const createdAt = sanitizeSnapshotTimestamp(
message?.message?.created_at ??
message?.event?.created_at ??
message?.timestamp,
);
const createdAt = resolveDirectMessageCreatedAt(message);
const kind =
Number.isFinite(message?.message?.kind)
@@ -459,7 +475,7 @@ function buildSnapshotFromMessages(messages, actorPubkey = "", resolvePreview =
continue;
}
const timestamp = sanitizeSnapshotTimestamp(message.timestamp);
const timestamp = resolveDirectMessageSortValue(message);
const preview =
typeof resolvePreview === "function"
? resolvePreview(message)
@@ -490,18 +506,12 @@ function normalizeDirectMessagePayload(message) {
return null;
}
const timestamp =
Number.isFinite(message?.timestamp)
? message.timestamp
: Number.isFinite(message?.message?.created_at)
? message.message.created_at
: Number.isFinite(message?.event?.created_at)
? message.event.created_at
: Date.now() / 1000;
const createdAt = resolveDirectMessageCreatedAt(message);
return {
...message,
timestamp,
created_at: createdAt,
timestamp: createdAt,
};
}
@@ -516,7 +526,10 @@ function mergeDirectMessageCache(existingMessages, incomingMessages) {
const eventId = normalized.event.id;
const existing = mergedIndex.get(eventId);
if (!existing || normalized.timestamp >= (existing.timestamp || 0)) {
if (
!existing ||
normalized.created_at >= resolveDirectMessageSortValue(existing)
) {
mergedIndex.set(eventId, normalized);
}
};
@@ -530,7 +543,9 @@ function mergeDirectMessageCache(existingMessages, incomingMessages) {
}
const mergedMessages = Array.from(mergedIndex.values());
mergedMessages.sort((a, b) => (b?.timestamp || 0) - (a?.timestamp || 0));
mergedMessages.sort(
(a, b) => resolveDirectMessageSortValue(b) - resolveDirectMessageSortValue(a),
);
return { messages: mergedMessages, index: mergedIndex };
}
@@ -856,17 +871,10 @@ export class NostrService {
return;
}
const normalized = {
...message,
timestamp:
Number.isFinite(message?.timestamp)
? message.timestamp
: Number.isFinite(message?.message?.created_at)
? message.message.created_at
: Number.isFinite(message?.event?.created_at)
? message.event.created_at
: Date.now() / 1000,
};
const normalized = normalizeDirectMessagePayload(message);
if (!normalized) {
return;
}
this.dmMessageIndex.set(eventId, normalized);
@@ -891,7 +899,9 @@ export class NostrService {
this.dmMessages.push(normalized);
}
this.dmMessages.sort((a, b) => (b?.timestamp || 0) - (a?.timestamp || 0));
this.dmMessages.sort(
(a, b) => resolveDirectMessageSortValue(b) - resolveDirectMessageSortValue(a),
);
if (actor) {
this.dmActorPubkey = actor;
}
@@ -954,8 +964,14 @@ export class NostrService {
return this.getDirectMessages();
}
this.dmMessages = hydrated;
this.dmMessageIndex = new Map();
if (force) {
this.dmMessages = [];
this.dmMessageIndex = new Map();
}
const merged = mergeDirectMessageCache(this.dmMessages, hydrated);
this.dmMessageIndex = merged.index;
this.dmMessages = merged.messages;
this.dmHydratedFromSnapshot = hydrated.length > 0;
const snapshot = this.getDirectMessages();
@@ -1027,8 +1043,8 @@ export class NostrService {
if (resolvedSince === null && initialLoad) {
let latestTimestamp = 0;
for (const message of Array.isArray(this.dmMessages) ? this.dmMessages : []) {
const timestamp = Number(message?.timestamp);
if (Number.isFinite(timestamp) && timestamp > latestTimestamp) {
const timestamp = resolveDirectMessageSortValue(message);
if (timestamp > latestTimestamp) {
latestTimestamp = timestamp;
}
}
+31 -9
View File
@@ -166,21 +166,39 @@ class ProfileCache {
return null;
}
const existingEntry = this.getProfileData(normalizedPubkey, "profile");
const existingProfile = existingEntry?.profile || {};
const existingName = sanitizeProfileString(existingProfile.name);
const existingPicture = sanitizeProfileMediaUrl(existingProfile.picture);
const existingAbout = sanitizeProfileString(existingProfile.about);
const existingWebsite = sanitizeProfileString(existingProfile.website);
const existingBanner = sanitizeProfileMediaUrl(existingProfile.banner);
const existingLud16 = sanitizeProfileString(existingProfile.lud16);
const existingLud06 = sanitizeProfileString(existingProfile.lud06);
const existingLightningAddress = sanitizeProfileString(
existingProfile.lightningAddress,
);
const normalized = {
name:
sanitizeProfileString(profile.name || profile.display_name) ||
existingName ||
"Unknown",
picture:
sanitizeProfileMediaUrl(profile.picture || profile.image) ||
existingPicture ||
"assets/svg/default-profile.svg",
};
const about = sanitizeProfileString(profile.about || profile.aboutMe);
const about =
sanitizeProfileString(profile.about || profile.aboutMe) || existingAbout;
if (about) {
normalized.about = about;
}
const website = sanitizeProfileString(profile.website || profile.url);
const website =
sanitizeProfileString(profile.website || profile.url) || existingWebsite;
if (website) {
normalized.website = website;
}
@@ -191,18 +209,19 @@ class ProfileCache {
profile.background ||
profile.cover ||
profile.cover_image ||
profile.coverImage
profile.coverImage,
);
if (banner) {
normalized.banner = banner;
const resolvedBanner = banner || existingBanner;
if (resolvedBanner) {
normalized.banner = resolvedBanner;
}
const lud16 = sanitizeProfileString(profile.lud16);
const lud16 = sanitizeProfileString(profile.lud16) || existingLud16;
if (lud16) {
normalized.lud16 = lud16;
}
const lud06 = sanitizeProfileString(profile.lud06);
const lud06 = sanitizeProfileString(profile.lud06) || existingLud06;
if (lud06) {
normalized.lud06 = lud06;
}
@@ -212,8 +231,11 @@ class ProfileCache {
lud16,
lud06,
].filter(Boolean);
if (lightningCandidates.length) {
normalized.lightningAddress = lightningCandidates[0];
const resolvedLightningAddress = lightningCandidates.length
? lightningCandidates[0]
: existingLightningAddress;
if (resolvedLightningAddress) {
normalized.lightningAddress = resolvedLightningAddress;
}
const entry = {