Fix hashtag preferences loading and profile persistence issues

- 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`.
This commit is contained in:
google-labs-jules[bot] committed 2026-01-18 02:09:04 +00:00
1 parent 983f67fa1b
commit a2de2b550d
7 files changed
+220 -124

No files matched your search

+26 -30
View File
@@ -1060,15 +1060,9 @@ export default class AuthService {
});
const newest = selectNewestEvent(aggregated);
if (!newest) {
return;
if (newest && this.nostrClient && typeof this.nostrClient.handleEvent === "function") {
this.nostrClient.handleEvent(newest);
}
const profile = buildProfileFromEvent(newest);
this.setProfileCacheEntry(normalized, profile, {
persist: true,
reason: "load-own-profile:background",
});
})
.catch((error) => {
this.log("[AuthService] Background profile refresh failed", error);
@@ -1096,11 +1090,12 @@ export default class AuthService {
if (fastResult?.events?.length) {
const newest = selectNewestEvent(fastResult.events);
if (newest) {
if (this.nostrClient && typeof this.nostrClient.handleEvent === "function") {
this.nostrClient.handleEvent(newest);
}
const profile = buildProfileFromEvent(newest);
this.setProfileCacheEntry(normalized, profile, {
persist: true,
reason: "load-own-profile:fast",
});
// setProfileCacheEntry now delegates to profileCache.setProfile, but handleEvent also does it.
// Doing it here returns the profile object which might be needed immediately.
background.catch(() => {});
return profile;
}
@@ -1159,24 +1154,25 @@ export default class AuthService {
}
}
if (newest?.content) {
const data = JSON.parse(newest.content);
const profile = {
name: data.display_name || data.name || FALLBACK_PROFILE.name,
picture: data.picture || FALLBACK_PROFILE.picture,
about: typeof data.about === "string" ? data.about : FALLBACK_PROFILE.about,
website:
typeof data.website === "string" ? data.website : FALLBACK_PROFILE.website,
banner:
typeof data.banner === "string" ? data.banner : FALLBACK_PROFILE.banner,
lud16: typeof data.lud16 === "string" ? data.lud16 : FALLBACK_PROFILE.lud16,
lud06: typeof data.lud06 === "string" ? data.lud06 : FALLBACK_PROFILE.lud06,
};
this.setProfileCacheEntry(normalized, profile, {
persist: true,
reason: forceRefresh ? "force-refresh" : "fetch-profile",
});
return profile;
if (newest) {
if (this.nostrClient && typeof this.nostrClient.handleEvent === "function") {
this.nostrClient.handleEvent(newest);
}
if (newest.content) {
const data = JSON.parse(newest.content);
const profile = {
name: data.display_name || data.name || FALLBACK_PROFILE.name,
picture: data.picture || FALLBACK_PROFILE.picture,
about: typeof data.about === "string" ? data.about : FALLBACK_PROFILE.about,
website:
typeof data.website === "string" ? data.website : FALLBACK_PROFILE.website,
banner:
typeof data.banner === "string" ? data.banner : FALLBACK_PROFILE.banner,
lud16: typeof data.lud16 === "string" ? data.lud16 : FALLBACK_PROFILE.lud16,
lud06: typeof data.lud06 === "string" ? data.lud06 : FALLBACK_PROFILE.lud06,
};
return profile;
}
}
} catch (error) {
this.log("[AuthService] Failed to fetch profile", error);