Browse Source

bug-fixes

master
Silberengel 1 month ago
parent
commit
31328eaa26
  1. 4
      src/lib/components/content/GifPicker.svelte
  2. 6
      src/lib/services/cache/cache-manager.ts
  3. 68
      src/lib/services/cache/deletion-tracker.ts
  4. 19
      src/lib/services/cache/event-cache.ts
  5. 2
      src/lib/services/cache/indexeddb-store.ts
  6. 16
      src/routes/cache/+page.svelte

4
src/lib/components/content/GifPicker.svelte

@ -342,7 +342,7 @@ @@ -342,7 +342,7 @@
pendingUpload = { file, fileUrl };
showMetadataForm = true;
// Reset metadata form
// Reset metadata form and prefill image URL with uploaded file URL
metadataForm = {
title: '',
summary: '',
@ -350,7 +350,7 @@ @@ -350,7 +350,7 @@
dim: '',
blurhash: '',
thumb: '',
image: '',
image: fileUrl, // Prefill with the uploaded GIF URL
content: ''
};
} catch (error) {

6
src/lib/services/cache/cache-manager.ts vendored

@ -140,6 +140,12 @@ export async function getAllCachedEvents( @@ -140,6 +140,12 @@ export async function getAllCachedEvents(
await tx.done;
// Filter out events that have deletion requests
const { getDeletedEventIds } = await import('./deletion-tracker.js');
const eventIds = events.map(e => e.id);
const deletedIds = await getDeletedEventIds(eventIds);
events = events.filter(e => !deletedIds.has(e.id));
// Apply search filter if provided
if (options.searchTerm) {
const searchLower = options.searchTerm.toLowerCase();

68
src/lib/services/cache/deletion-tracker.ts vendored

@ -0,0 +1,68 @@ @@ -0,0 +1,68 @@
/**
* Track deletion requests to prevent re-caching deleted events
* Uses cached kind 5 (deletion request) events from the cache
*/
import { getDB } from './indexeddb-store.js';
import { KIND } from '../../types/kind-lookup.js';
import type { CachedEvent } from './event-cache.js';
/**
* Get all event IDs that have deletion requests
* Queries the cache for kind 5 events and extracts event IDs from their 'e' tags
*/
async function getDeletedEventIdsFromCache(): Promise<Set<string>> {
const deletedSet = new Set<string>();
try {
const db = await getDB();
const tx = db.transaction('events', 'readonly');
const index = tx.store.index('kind');
// Get all kind 5 (deletion request) events
for await (const cursor of index.iterate(KIND.EVENT_DELETION)) {
const deletionEvent = cursor.value as CachedEvent;
// Extract event IDs from 'e' tags
if (deletionEvent.tags) {
for (const tag of deletionEvent.tags) {
if (tag[0] === 'e' && tag[1]) {
deletedSet.add(tag[1]);
}
}
}
}
await tx.done;
} catch (error) {
console.debug('Error getting deleted event IDs from cache:', error);
}
return deletedSet;
}
/**
* Check if an event is marked as deleted (has a deletion request in cache)
*/
export async function isEventDeleted(eventId: string): Promise<boolean> {
try {
const deletedIds = await getDeletedEventIdsFromCache();
return deletedIds.has(eventId);
} catch (error) {
console.debug('Error checking if event is deleted:', error);
return false;
}
}
/**
* Check if any of the given event IDs are marked as deleted
* Returns a Set of deleted event IDs for efficient lookup
*/
export async function getDeletedEventIds(eventIds: string[]): Promise<Set<string>> {
try {
const deletedIds = await getDeletedEventIdsFromCache();
// Return intersection of requested IDs and deleted IDs
return new Set(eventIds.filter(id => deletedIds.has(id)));
} catch (error) {
console.debug('Error checking deleted events:', error);
return new Set<string>();
}
}

19
src/lib/services/cache/event-cache.ts vendored

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
*/
import { getDB } from './indexeddb-store.js';
import { isEventDeleted, getDeletedEventIds } from './deletion-tracker.js';
import type { NostrEvent } from '../../types/nostr.js';
export interface CachedEvent extends NostrEvent {
@ -14,6 +15,11 @@ export interface CachedEvent extends NostrEvent { @@ -14,6 +15,11 @@ export interface CachedEvent extends NostrEvent {
*/
export async function cacheEvent(event: NostrEvent): Promise<void> {
try {
// Don't cache events that have deletion requests
if (await isEventDeleted(event.id)) {
return;
}
const db = await getDB();
const cached: CachedEvent = {
...event,
@ -31,9 +37,20 @@ export async function cacheEvent(event: NostrEvent): Promise<void> { @@ -31,9 +37,20 @@ export async function cacheEvent(event: NostrEvent): Promise<void> {
*/
export async function cacheEvents(events: NostrEvent[]): Promise<void> {
try {
if (events.length === 0) return;
// Check which events are marked as deleted
const eventIds = events.map(e => e.id);
const deletedIds = await getDeletedEventIds(eventIds);
// Filter out deleted events
const eventsToCache = events.filter(e => !deletedIds.has(e.id));
if (eventsToCache.length === 0) return;
const db = await getDB();
const tx = db.transaction('events', 'readwrite');
for (const event of events) {
for (const event of eventsToCache) {
const cached: CachedEvent = {
...event,
cached_at: Date.now()

2
src/lib/services/cache/indexeddb-store.ts vendored

@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
import { openDB, type IDBPDatabase } from 'idb';
const DB_NAME = 'aitherboard';
const DB_VERSION = 2; // Incremented to force upgrade when stores are missing
const DB_VERSION = 3; // Incremented to add deletion_requests store
export interface DatabaseSchema {
events: {

16
src/routes/cache/+page.svelte vendored

@ -3,11 +3,12 @@ @@ -3,11 +3,12 @@
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
import { getCacheStats, getAllCachedEvents, clearAllCache, clearCacheByKind, clearCacheByKinds, clearCacheByDate, deleteEventById, type CacheStats } from '../../lib/services/cache/cache-manager.js';
import { cacheEvent } from '../../lib/services/cache/event-cache.js';
import type { CachedEvent } from '../../lib/services/cache/event-cache.js';
import { KIND, getKindInfo } from '../../lib/types/kind-lookup.js';
import { nip19 } from 'nostr-tools';
import { sessionManager } from '../../lib/services/auth/session-manager.js';
import { signAndPublish } from '../../lib/services/nostr/auth-handler.js';
import { nostrClient } from '../../lib/services/nostr/nostr-client.js';
import type { NostrEvent } from '../../lib/types/nostr.js';
let stats = $state<CacheStats | null>(null);
@ -352,9 +353,18 @@ @@ -352,9 +353,18 @@
content: ''
};
const result = await signAndPublish(deleteEvent);
// Sign the deletion request event first
const signedDeleteEvent = await sessionManager.signEvent(deleteEvent);
// Cache the deletion request event so it prevents re-caching of the deleted event
// This must happen before publishing to ensure it's in cache
await cacheEvent(signedDeleteEvent);
// Publish the already-signed event directly
// Note: nostrClient.publish() will also cache it, but that's fine (idempotent)
const result = await nostrClient.publish(signedDeleteEvent);
if (result.success.length > 0) {
// Also delete from cache
// Also delete the original event from cache
try {
await deleteEventById(event.id);
events = events.filter(e => e.id !== event.id);

Loading…
Cancel
Save