Update docs, tweak url based event derivation

This commit is contained in:
Jon Staab
2025-11-20 15:08:59 -08:00
parent 6d36f5a912
commit 2fec078a5b
12 changed files with 154 additions and 317 deletions
+66 -38
View File
@@ -1,74 +1,102 @@
# Repository
Reactive Svelte stores for querying and mapping events from a Repository with automatic updates.
Reactive Svelte stores for querying events from a Repository with automatic updates.
## Functions
## Event Stores
### deriveEventsMapped(repository, options)
```typescript
// Derive map of events by ID
deriveEventsById(options: {
repository: Repository
filters: Filter[]
includeDeleted?: boolean
}): Readable<Map<string, TrustedEvent>>
Creates a reactive store that maps events to custom items and keeps them synchronized with repository updates.
// Convert events by ID to array
deriveEvents(eventsByIdStore: Readable<Map<string, TrustedEvent>>): Readable<TrustedEvent[]>
**Options:**
- `filters` - Array of Nostr filters to query events
- `eventToItem` - Function to transform events to items (can return Promise)
- `itemToEvent` - Function to extract the event from an item
- `throttle?` - Throttle updates (milliseconds, default: 0)
- `includeDeleted?` - Include deleted events (default: false)
// Sort events ascending by created_at
deriveEventsAsc(eventsStore: Readable<TrustedEvent[]>): Readable<TrustedEvent[]>
### deriveEvents(repository, options)
// Sort events descending by created_at
deriveEventsDesc(eventsStore: Readable<TrustedEvent[]>): Readable<TrustedEvent[]>
Creates a reactive store of events without transformation.
// Derive single event by ID or address
deriveEvent(repository: Repository, idOrAddress: string): Readable<TrustedEvent | undefined>
**Options:**
- `filters` - Array of Nostr filters
- `throttle?` - Throttle updates
- `includeDeleted?` - Include deleted events
// Track if event is deleted
deriveIsDeleted(repository: Repository, event: TrustedEvent): Readable<boolean>
```
### deriveEvent(repository, idOrAddress)
## Indexed Collections
Creates a reactive store for a single event by ID or address.
```typescript
// Create indexed map of items from repository events
deriveItemsByKey<T>(options: {
repository: Repository
filters: Filter[]
eventToItem: (event: TrustedEvent) => MaybeAsync<Maybe<T>>
getKey: (item: T) => string
includeDeleted?: boolean
}): Readable<Map<string, T>>
### deriveIsDeleted(repository, event)
// Convert itemsByKey map to array
deriveItems<T>(itemsByKeyStore: Readable<Map<string, T>>): Readable<T[]>
Creates a reactive store that tracks whether an event is deleted.
// Create function to derive single item by key
makeDeriveItem<T>(
itemsByKeyStore: Readable<Map<string, T>>,
onDerive?: (key: string, ...args: any[]) => void
): (key: string, ...args: any[]) => Readable<T | undefined>
### deriveIsDeletedByAddress(repository, event)
// Create cached loader with staleness checking and exponential backoff
makeLoadItem<T>(
loadItem: (key: string, ...args: any[]) => Promise<unknown>,
getItem: (key: string) => T | undefined,
options?: {getFetched?, setFetched?, timeout?}
): (key: string, ...args: any[]) => Promise<T | undefined>
Creates a reactive store that tracks whether an event is deleted by address.
// Create loader that always fetches fresh data
makeForceLoadItem<T>(
loadItem: (key: string, ...args: any[]) => Promise<unknown>,
getItem: (key: string) => T | undefined
): (key: string, ...args: any[]) => Promise<T | undefined>
// Optimized getter that switches to subscription when hot
getter<T>(store: Readable<T>, options?: {threshold?: number}): () => T
```
## Example
```typescript
import {Repository} from "@welshman/net"
import {deriveEventsMapped, deriveEvents} from "@welshman/store"
import {deriveEventsById, deriveEvents, deriveItemsByKey, deriveItems} from "@welshman/store"
import {readProfile, PROFILE} from "@welshman/util"
const repository = new Repository()
// Reactive store of text notes
const textNotes = deriveEvents(repository, {
filters: [{kinds: [1], limit: 100}],
throttle: 100
const noteEventsById = deriveEventsById({
repository,
filters: [{kinds: [1], limit: 100}]
})
const notes = deriveEvents(noteEventsById)
// Reactive store of profiles mapped to custom objects
const profiles = deriveEventsMapped(repository, {
// Reactive store of profiles indexed by pubkey
const profilesByPubkey = deriveItemsByKey({
repository,
filters: [{kinds: [PROFILE]}],
eventToItem: event => readProfile(event),
itemToEvent: profile => profile.event,
includeDeleted: false
getKey: profile => profile.event.pubkey
})
const profiles = deriveItems(profilesByPubkey)
// Subscribe to updates
textNotes.subscribe(notes => {
console.log(`Found ${notes.length} text notes`)
notes.subscribe($notes => {
console.log(`Found ${$notes.length} text notes`)
})
profiles.subscribe(profiles => {
console.log(`Found ${profiles.length} profiles`)
profiles.subscribe($profiles => {
console.log(`Found ${$profiles.length} profiles`)
})
// Add some events to the repository
repository.publish(someTextNoteEvent)
repository.publish(someProfileEvent)
```