Cache space nav items and fix meta storage

This commit is contained in:
Jon Staab 2026-08-17 10:17:12 -07:00
parent 0f448e0b5a
commit 01a79d570b
3 changed files with 34 additions and 7 deletions

View file

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import {derived} from "svelte/store" import {derived} from "svelte/store"
import {getJson, setJson} from "@welshman/lib"
import {EVENT_TIME, ZAP_GOAL, THREAD, CLASSIFIED, PINBOARD, POLL} from "@welshman/util" import {EVENT_TIME, ZAP_GOAL, THREAD, CLASSIFIED, PINBOARD, POLL} from "@welshman/util"
import Magnifier from "@assets/icons/magnifier.svg?dataurl" import Magnifier from "@assets/icons/magnifier.svg?dataurl"
import UsersGroup from "@assets/icons/users-group-rounded.svg?dataurl" import UsersGroup from "@assets/icons/users-group-rounded.svg?dataurl"
@ -38,17 +39,23 @@
const calendarPath = makeSpacePath(url, "calendar") const calendarPath = makeSpacePath(url, "calendar")
const pollsPath = makeSpacePath(url, "polls") const pollsPath = makeSpacePath(url, "polls")
// Content events aren't retained across page loads, so seed with the kinds seen last time
// to keep the nav from re-populating as they load in the background.
const spaceKindsKey = `space-kinds:${url}`
const cachedKinds: number[] = getJson(spaceKindsKey) ?? []
const spaceKinds = derived( const spaceKinds = derived(
deriveEventsForUrl(url, [{kinds: CONTENT_KINDS}]), deriveEventsForUrl(url, [{kinds: CONTENT_KINDS}]),
$events => new Set($events.map(e => e.kind)), $events => new Set([...cachedKinds, ...$events.map(e => e.kind)]),
) )
const boardEvents = deriveEventsForUrl(url, [{kinds: [PINBOARD]}])
const hasNip29 = $derived($relay?.hasNip(29) ?? false) const hasNip29 = $derived($relay?.hasNip(29) ?? false)
const supportedMethods = deriveSpaceSupportedMethods(url) const supportedMethods = deriveSpaceSupportedMethods(url)
const showLibrary = $derived($boardEvents.length > 0 || $supportedMethods.includes("signevent")) const showLibrary = $derived($spaceKinds.has(PINBOARD) || $supportedMethods.includes("signevent"))
const openSearch = () => pushModal(SpaceSearch, {url}) const openSearch = () => pushModal(SpaceSearch, {url})
$effect(() => setJson(spaceKindsKey, [...$spaceKinds]))
</script> </script>
<SecondaryNavItem href={makeSpacePath(url, "about")}> <SecondaryNavItem href={makeSpacePath(url, "about")}>

View file

@ -6,6 +6,7 @@ import {
DIRECT_MESSAGE_FILE, DIRECT_MESSAGE_FILE,
EVENT_TIME, EVENT_TIME,
GENERIC_REPOST, GENERIC_REPOST,
PINBOARD,
POLL, POLL,
REACTION, REACTION,
REPORT, REPORT,
@ -40,7 +41,7 @@ if (ENABLE_ZAPS) {
REACTION_KINDS.push(ZAP_RECEIPT) REACTION_KINDS.push(ZAP_RECEIPT)
} }
export const CONTENT_KINDS = [ZAP_GOAL, EVENT_TIME, THREAD, CLASSIFIED, POLL] export const CONTENT_KINDS = [ZAP_GOAL, EVENT_TIME, THREAD, CLASSIFIED, POLL, PINBOARD]
export const DM_KINDS = [DIRECT_MESSAGE, DIRECT_MESSAGE_FILE] export const DM_KINDS = [DIRECT_MESSAGE, DIRECT_MESSAGE_FILE]

View file

@ -250,7 +250,8 @@ class Storage {
} }
private syncEvents = () => { private syncEvents = () => {
const table = this.db.table<TrustedEvent>("events") const eventsTable = this.db.table<TrustedEvent>("events")
const trackerTable = this.db.table<TrackerItem>("tracker")
return on( return on(
this.app.repository, this.app.repository,
@ -273,11 +274,26 @@ class Storage {
} }
if (add.length > 0) { if (add.length > 0) {
await table.bulkPut(add) // The ingest policy tracks an event before publishing it, so by the time the
// repository reports it, its provenance is already in the tracker — persist the
// two together so an event is never saved without the relays it came from.
const items: TrackerItem[] = []
for (const {id} of add) {
const relays = Array.from(this.app.tracker.getRelays(id))
if (relays.length > 0) {
items.push({id, relays})
}
}
await eventsTable.bulkPut(add)
await trackerTable.bulkPut(items)
} }
if (remove.size > 0) { if (remove.size > 0) {
await table.bulkDelete(remove) await eventsTable.bulkDelete(remove)
await trackerTable.bulkDelete(remove)
} }
}), }),
) )
@ -312,6 +328,9 @@ class Storage {
for (const id of ids) { for (const id of ids) {
const event = this.app.repository.getEvent(id) const event = this.app.repository.getEvent(id)
// A brand-new event is tracked before it's published, so it isn't queryable here —
// syncEvents persists its provenance along with the event itself. This pass only
// records additional relays for events we already have.
if (!event || !shouldPersistEvent(event)) continue if (!event || !shouldPersistEvent(event)) continue
const relays = Array.from(this.app.tracker.getRelays(id)) const relays = Array.from(this.app.tracker.getRelays(id))