A social knowledge tool for researchers built on ATProto
at development 3.1 kB view raw
1import { Result, ok, err } from '../../../../shared/core/Result'; 2import { ICardRepository } from '../../domain/ICardRepository'; 3import { Card } from '../../domain/Card'; 4import { CardId } from '../../domain/value-objects/CardId'; 5import { CuratorId } from '../../domain/value-objects/CuratorId'; 6import { URL } from '../../domain/value-objects/URL'; 7 8export class InMemoryCardRepository implements ICardRepository { 9 private cards: Map<string, Card> = new Map(); 10 private shouldFail: boolean = false; 11 private shouldFailSave: boolean = false; 12 13 private clone(card: Card): Card { 14 // Simple clone - in a real implementation you'd want proper deep cloning 15 const cardResult = Card.create( 16 { 17 curatorId: card.props.curatorId, 18 type: card.type, 19 content: card.content, 20 parentCardId: card.parentCardId, 21 url: card.url, 22 publishedRecordId: card.publishedRecordId, 23 libraryMemberships: card.libraryMemberships, 24 libraryCount: card.libraryCount, 25 createdAt: card.createdAt, 26 updatedAt: card.updatedAt, 27 }, 28 card.id, 29 ); 30 31 if (cardResult.isErr()) { 32 throw new Error(`Failed to clone card: ${cardResult.error.message}`); 33 } 34 35 return cardResult.value; 36 } 37 38 async findById(id: CardId): Promise<Result<Card | null>> { 39 if (this.shouldFail) { 40 return err(new Error('Simulated find failure')); 41 } 42 try { 43 const card = this.cards.get(id.getStringValue()); 44 return ok(card ? this.clone(card) : null); 45 } catch (error) { 46 return err(error as Error); 47 } 48 } 49 50 async findUsersUrlCardByUrl( 51 url: URL, 52 curatorId: CuratorId, 53 ): Promise<Result<Card | null>> { 54 try { 55 const card = Array.from(this.cards.values()).find( 56 (card) => 57 card.type.value === 'URL' && 58 card.url?.value === url.value && 59 card.props.curatorId.equals(curatorId), 60 ); 61 return ok(card ? this.clone(card) : null); 62 } catch (error) { 63 return err(error as Error); 64 } 65 } 66 67 async save(card: Card): Promise<Result<void>> { 68 if (this.shouldFailSave || this.shouldFail) { 69 return err(new Error('Simulated save failure')); 70 } 71 try { 72 this.cards.set(card.cardId.getStringValue(), this.clone(card)); 73 return ok(undefined); 74 } catch (error) { 75 return err(error as Error); 76 } 77 } 78 79 async delete(cardId: CardId): Promise<Result<void>> { 80 try { 81 this.cards.delete(cardId.getStringValue()); 82 return ok(undefined); 83 } catch (error) { 84 return err(error as Error); 85 } 86 } 87 88 setShouldFail(shouldFail: boolean): void { 89 this.shouldFail = shouldFail; 90 } 91 92 setShouldFailSave(shouldFailSave: boolean): void { 93 this.shouldFailSave = shouldFailSave; 94 } 95 96 // Helper methods for testing 97 public clear(): void { 98 this.cards.clear(); 99 this.shouldFail = false; 100 this.shouldFailSave = false; 101 } 102 103 public getStoredCard(id: CardId): Card | undefined { 104 return this.cards.get(id.getStringValue()); 105 } 106 107 public getAllCards(): Card[] { 108 return Array.from(this.cards.values()).map((card) => this.clone(card)); 109 } 110}