Lab/Marketplace/Stash audit: useLabProfile picks newest revision (1.2.38)
Audited all three remaining surfaces. Two of them needed no changes: MARKETPLACE / GEARSWAP — sound. useMarkListingSold preserves every tag and flips only `status` (author-gated, right comment explaining why it doesn't rebuild). Queries validate + dedupe, exclude showcase-only Stash items from the sellable market, and GearSwap filters out expired/sold listings and separates WTB from WTS. No bugs. STASH — sound, and notably careful. The private list is one NIP-44 encrypted-to-self blob; all three mutations (add/update/remove) use fetchLatestStash() (fetch-before-write) which falls back to non-empty cache and THROWS rather than risk clobbering the user's gear, and is Amber-gated (staleTime: Infinity). The public/private showcase reconciliation in StashPage is complete: going public publishes the kind-30402 showcase event, and going private / deleting / converting to a wishlist item all call unpublishItem — so a public event can't linger after an item is made private (no privacy leak). No bugs. THE LAB — the collective join-request clobber was already fixed in 1.2.37. One robustness gap remained: useLabProfile fetched the profile with limit:1 and trusted whatever came back. Relays can hold multiple revisions of an addressable event, so a stale revision could win — showing an old bio or, worse, a roster missing recently-approved members. Now fetches a few (limit:10) and reduces to the newest created_at, matching the pickMostRecent discipline already in useCrew. On detail pages an author filter is always set, so newest-of-one-author is exactly right. Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
parent
b6b3931ecc
commit
56e2b17990
2 changed files with 11 additions and 3 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "skate-spots",
|
"name": "skate-spots",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.2.37",
|
"version": "1.2.38",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"homepage": "https://skate-spots.com",
|
"homepage": "https://skate-spots.com",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,10 @@ export function useLabProfile(identifier: string, pubkey?: string) {
|
||||||
} = {
|
} = {
|
||||||
kinds: LAB_KINDS,
|
kinds: LAB_KINDS,
|
||||||
'#d': [identifier],
|
'#d': [identifier],
|
||||||
limit: 1,
|
// Relays can hold multiple revisions of an addressable event; fetch a
|
||||||
|
// few and pick the newest rather than trusting whatever `limit: 1`
|
||||||
|
// returns (which may be a stale revision, dropping members/edits).
|
||||||
|
limit: 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (pubkey) filter.authors = [pubkey];
|
if (pubkey) filter.authors = [pubkey];
|
||||||
|
|
@ -158,7 +161,12 @@ export function useLabProfile(identifier: string, pubkey?: string) {
|
||||||
|
|
||||||
if (events.length === 0) return null;
|
if (events.length === 0) return null;
|
||||||
|
|
||||||
return parseLabProfile(events[0]);
|
// Newest revision wins.
|
||||||
|
const newest = events.reduce((latest, current) =>
|
||||||
|
current.created_at > latest.created_at ? current : latest,
|
||||||
|
);
|
||||||
|
|
||||||
|
return parseLabProfile(newest);
|
||||||
},
|
},
|
||||||
enabled: !!identifier,
|
enabled: !!identifier,
|
||||||
staleTime: 30000,
|
staleTime: 30000,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue