You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
141 lines
4.2 KiB
141 lines
4.2 KiB
import type { NDKEvent } from '@nostr-dev-kit/ndk'; |
|
import type { DisplayLimits } from '$lib/stores/displayLimits'; |
|
import type { VisualizationConfig } from '$lib/stores/visualizationConfig'; |
|
|
|
/** |
|
* Filters events based on display limits and allowed kinds |
|
* @param events - All available events |
|
* @param limits - Display limit settings |
|
* @param config - Visualization configuration (optional) |
|
* @returns Filtered events that should be displayed |
|
*/ |
|
export function filterByDisplayLimits(events: NDKEvent[], limits: DisplayLimits, config?: VisualizationConfig): NDKEvent[] { |
|
const result: NDKEvent[] = []; |
|
const kindCounts = new Map<number, number>(); |
|
|
|
for (const event of events) { |
|
// First check if the event kind is allowed and not disabled |
|
if (config && event.kind !== undefined) { |
|
if (!config.allowedKinds.includes(event.kind)) { |
|
continue; // Skip events with disallowed kinds |
|
} |
|
if (config.disabledKinds.includes(event.kind)) { |
|
continue; // Skip temporarily disabled kinds |
|
} |
|
} |
|
|
|
const kind = event.kind; |
|
if (kind === undefined) continue; |
|
|
|
// Get the limit for this event kind from the config |
|
const eventConfig = config?.eventConfigs.find(ec => ec.kind === kind); |
|
const limit = eventConfig?.limit; |
|
|
|
// Special handling for content kinds (30041, 30818) with showAll option |
|
if ((kind === 30041 || kind === 30818) && eventConfig?.showAll) { |
|
// Show all content events when showAll is true |
|
result.push(event); |
|
// Still update the count for UI display |
|
const currentCount = kindCounts.get(kind) || 0; |
|
kindCounts.set(kind, currentCount + 1); |
|
} else if (limit !== undefined) { |
|
// Normal limit checking |
|
const currentCount = kindCounts.get(kind) || 0; |
|
if (currentCount < limit) { |
|
result.push(event); |
|
kindCounts.set(kind, currentCount + 1); |
|
} |
|
} else { |
|
// No limit configured, add the event |
|
result.push(event); |
|
} |
|
} |
|
|
|
return result; |
|
} |
|
|
|
/** |
|
* Detects events that are referenced but not present in the current set |
|
* @param events - Current events |
|
* @param existingIds - Set of all known event IDs |
|
* @returns Set of missing event identifiers |
|
*/ |
|
export function detectMissingEvents(events: NDKEvent[], existingIds: Set<string>): Set<string> { |
|
const missing = new Set<string>(); |
|
|
|
for (const event of events) { |
|
// Check 'a' tags for NIP-33 references (kind:pubkey:d-tag) |
|
const aTags = event.getMatchingTags('a'); |
|
for (const aTag of aTags) { |
|
if (aTag.length < 2) continue; |
|
|
|
const identifier = aTag[1]; |
|
const parts = identifier.split(':'); |
|
|
|
if (parts.length >= 3) { |
|
const [kind, pubkey, dTag] = parts; |
|
// Create a synthetic ID for checking |
|
const syntheticId = `${kind}:${pubkey}:${dTag}`; |
|
|
|
// Check if we have an event matching this reference |
|
const hasEvent = Array.from(existingIds).some(id => { |
|
// This is a simplified check - in practice, you'd need to |
|
// check the actual event's d-tag value |
|
return id === dTag || id === syntheticId; |
|
}); |
|
|
|
if (!hasEvent) { |
|
missing.add(dTag); |
|
} |
|
} |
|
} |
|
|
|
// Check 'e' tags for direct event references |
|
const eTags = event.getMatchingTags('e'); |
|
for (const eTag of eTags) { |
|
if (eTag.length < 2) continue; |
|
|
|
const eventId = eTag[1]; |
|
if (!existingIds.has(eventId)) { |
|
missing.add(eventId); |
|
} |
|
} |
|
} |
|
|
|
return missing; |
|
} |
|
|
|
/** |
|
* Groups events by kind for easier counting and display |
|
*/ |
|
export function groupEventsByKind(events: NDKEvent[]): Map<number, NDKEvent[]> { |
|
const groups = new Map<number, NDKEvent[]>(); |
|
|
|
for (const event of events) { |
|
const kind = event.kind; |
|
if (kind !== undefined) { |
|
if (!groups.has(kind)) { |
|
groups.set(kind, []); |
|
} |
|
groups.get(kind)!.push(event); |
|
} |
|
} |
|
|
|
return groups; |
|
} |
|
|
|
/** |
|
* Counts events by kind |
|
*/ |
|
export function countEventsByKind(events: NDKEvent[]): Map<number, number> { |
|
const counts = new Map<number, number>(); |
|
|
|
for (const event of events) { |
|
const kind = event.kind; |
|
if (kind !== undefined) { |
|
counts.set(kind, (counts.get(kind) || 0) + 1); |
|
} |
|
} |
|
|
|
return counts; |
|
} |