Fetch, cache, and update profile data

This commit is contained in:
2026-08-19 15:11:31 -06:00
parent c9a6304926
commit 0f0874a07a
3 changed files with 58 additions and 0 deletions
+42
View File
@@ -1,10 +1,12 @@
import Service, { service } from '@ember/service'; import Service, { service } from '@ember/service';
import { tracked } from '@glimmer/tracking'; import { tracked } from '@glimmer/tracking';
import { from } from 'rxjs';
import { EventStore } from 'applesauce-core/event-store'; import { EventStore } from 'applesauce-core/event-store';
import { ProfileModel } from 'applesauce-core/models/profile'; import { ProfileModel } from 'applesauce-core/models/profile';
import { MailboxesModel } from 'applesauce-core/models/mailboxes'; import { MailboxesModel } from 'applesauce-core/models/mailboxes';
import { npubEncode } from 'applesauce-core/helpers/pointers'; import { npubEncode } from 'applesauce-core/helpers/pointers';
import { persistEventsToCache } from 'applesauce-core/helpers/event-cache'; import { persistEventsToCache } from 'applesauce-core/helpers/event-cache';
import { createEventLoaderForStore } from 'applesauce-loaders/loaders';
import { NostrIDB, openDB } from 'nostr-idb'; import { NostrIDB, openDB } from 'nostr-idb';
import { import {
excludeRequiredRelays, excludeRequiredRelays,
@@ -35,12 +37,14 @@ export default class NostrDataService extends Service {
@tracked blossomServers = []; @tracked blossomServers = [];
@tracked placePhotos = []; @tracked placePhotos = [];
@tracked myContributionEvents = []; @tracked myContributionEvents = [];
@tracked profiles = {};
_profileSub = null; _profileSub = null;
_mailboxesSub = null; _mailboxesSub = null;
_blossomSub = null; _blossomSub = null;
_photosSub = null; _photosSub = null;
_contributionsSub = null; _contributionsSub = null;
_profileModelSubs = new Map();
_requestSub = null; _requestSub = null;
_cachePromise = null; _cachePromise = null;
@@ -81,6 +85,13 @@ export default class NostrDataService extends Service {
maxBatchSize: 100, maxBatchSize: 100,
} }
); );
// Set up the event loader so replaceable/event subscriptions auto-fetch
// from cache → relay hints → lookup relays with batching and dedup
createEventLoaderForStore(this.store, this.nostrRelay.pool, {
cacheRequest: (filters) => from(this.cache.query(filters)),
lookupRelays: DIRECTORY_RELAYS,
});
}); });
// Feed events from the relay pool into the event store // Feed events from the relay pool into the event store
@@ -218,6 +229,7 @@ export default class NostrDataService extends Service {
} }
this.placePhotos = []; this.placePhotos = [];
this._clearProfileSubs();
if (!place || !place.osmId || !place.osmType) { if (!place || !place.osmId || !place.osmType) {
return; return;
@@ -235,6 +247,8 @@ export default class NostrDataService extends Service {
]) ])
.subscribe((events) => { .subscribe((events) => {
this.placePhotos = events; this.placePhotos = events;
const pubkeys = [...new Set(events.map((e) => e.pubkey))];
this.loadProfiles(pubkeys);
}); });
try { try {
@@ -331,6 +345,33 @@ export default class NostrDataService extends Service {
}); });
} }
loadProfiles(pubkeys) {
const newPubkeys = pubkeys.filter(
(pk) => pk && !this._profileModelSubs.has(pk)
);
for (const pubkey of newPubkeys) {
const sub = this.store
.model(ProfileModel, pubkey)
.subscribe((profileContent) => {
this.profiles = { ...this.profiles, [pubkey]: profileContent };
});
this._profileModelSubs.set(pubkey, sub);
}
}
getProfile(pubkey) {
return this.profiles[pubkey];
}
_clearProfileSubs() {
for (const sub of this._profileModelSubs.values()) {
sub.unsubscribe();
}
this._profileModelSubs.clear();
this.profiles = {};
}
async loadProfile(pubkey) { async loadProfile(pubkey) {
if (!pubkey) return; if (!pubkey) return;
@@ -466,6 +507,7 @@ export default class NostrDataService extends Service {
this._contributionsSub.unsubscribe(); this._contributionsSub.unsubscribe();
this._contributionsSub = null; this._contributionsSub = null;
} }
this._clearProfileSubs();
} }
willDestroy() { willDestroy() {
+1
View File
@@ -105,6 +105,7 @@
"@noble/hashes": "^2.3.0", "@noble/hashes": "^2.3.0",
"@waysidemapping/pinhead": "^15.25.0", "@waysidemapping/pinhead": "^15.25.0",
"applesauce-core": "^6.2.0", "applesauce-core": "^6.2.0",
"applesauce-loaders": "^6.2.0",
"applesauce-relay": "^6.2.1", "applesauce-relay": "^6.2.1",
"applesauce-signers": "^6.2.2", "applesauce-signers": "^6.2.2",
"blurhash": "^2.0.5", "blurhash": "^2.0.5",
+15
View File
@@ -20,6 +20,9 @@ importers:
applesauce-core: applesauce-core:
specifier: ^6.2.0 specifier: ^6.2.0
version: 6.2.0(supports-color@10.2.2)(typescript@5.9.3) version: 6.2.0(supports-color@10.2.2)(typescript@5.9.3)
applesauce-loaders:
specifier: ^6.2.0
version: 6.2.0(supports-color@10.2.2)(typescript@5.9.3)
applesauce-relay: applesauce-relay:
specifier: ^6.2.1 specifier: ^6.2.1
version: 6.2.1(supports-color@10.2.2)(typescript@5.9.3) version: 6.2.1(supports-color@10.2.2)(typescript@5.9.3)
@@ -2636,6 +2639,9 @@ packages:
applesauce-core@6.2.0: applesauce-core@6.2.0:
resolution: {integrity: sha512-O6AlVyzqcuIhTOIuexm6UWmx7mRIa2D98gJP7K7vFGf90YdtvSH78AsKQWZXJ0Pk/K14at+9zkwfCkFr7ghgNw==} resolution: {integrity: sha512-O6AlVyzqcuIhTOIuexm6UWmx7mRIa2D98gJP7K7vFGf90YdtvSH78AsKQWZXJ0Pk/K14at+9zkwfCkFr7ghgNw==}
applesauce-loaders@6.2.0:
resolution: {integrity: sha512-isU2BuoVFhugv4WxdbUFrqm7mCNgsGrMU4BYcNqMm8qAVpVb3L7K3I1hlkIZWwOvNTkhoYO/u0utgwnkQj4Hrg==}
applesauce-relay@6.2.1: applesauce-relay@6.2.1:
resolution: {integrity: sha512-YIUHEtL2Fl5FZjeKYe/IuwL3OnMUNP2j4ydSr3iZDeHEZSEda4d1PoChefiNhtjE/U/F5OBHEbAX1zCHRZoxpg==} resolution: {integrity: sha512-YIUHEtL2Fl5FZjeKYe/IuwL3OnMUNP2j4ydSr3iZDeHEZSEda4d1PoChefiNhtjE/U/F5OBHEbAX1zCHRZoxpg==}
@@ -9354,6 +9360,15 @@ snapshots:
- supports-color - supports-color
- typescript - typescript
applesauce-loaders@6.2.0(supports-color@10.2.2)(typescript@5.9.3):
dependencies:
applesauce-core: 6.2.0(supports-color@10.2.2)(typescript@5.9.3)
nanoid: 5.1.9
rxjs: 7.8.2
transitivePeerDependencies:
- supports-color
- typescript
applesauce-relay@6.2.1(supports-color@10.2.2)(typescript@5.9.3): applesauce-relay@6.2.1(supports-color@10.2.2)(typescript@5.9.3):
dependencies: dependencies:
'@noble/hashes': 2.3.0 '@noble/hashes': 2.3.0