A social knowledge tool for researchers built on ATProto
at main 138 lines 4.4 kB view raw
1import { Result, ok, err } from '../../../../shared/core/Result'; 2import { ICollectionRepository } from '../../domain/ICollectionRepository'; 3import { Collection } from '../../domain/Collection'; 4import { CollectionId } from '../../domain/value-objects/CollectionId'; 5import { CardId } from '../../domain/value-objects/CardId'; 6import { CuratorId } from '../../domain/value-objects/CuratorId'; 7 8export class InMemoryCollectionRepository implements ICollectionRepository { 9 private static instance: InMemoryCollectionRepository; 10 private collections: Map<string, Collection> = new Map(); 11 12 private constructor() {} 13 14 public static getInstance(): InMemoryCollectionRepository { 15 if (!InMemoryCollectionRepository.instance) { 16 InMemoryCollectionRepository.instance = 17 new InMemoryCollectionRepository(); 18 } 19 return InMemoryCollectionRepository.instance; 20 } 21 22 private clone(collection: Collection): Collection { 23 // Simple clone - in a real implementation you'd want proper deep cloning 24 const collectionResult = Collection.create( 25 { 26 authorId: collection.authorId, 27 name: collection.name.value, 28 description: collection.description?.value, 29 accessType: collection.accessType, 30 collaboratorIds: collection.collaboratorIds, 31 cardLinks: collection.cardLinks, 32 cardCount: collection.cardCount, 33 publishedRecordId: collection.publishedRecordId, 34 createdAt: collection.createdAt, 35 updatedAt: collection.updatedAt, 36 }, 37 collection.id, 38 ); 39 40 if (collectionResult.isErr()) { 41 throw new Error( 42 `Failed to clone collection: ${collectionResult.error.message}`, 43 ); 44 } 45 46 return collectionResult.value; 47 } 48 49 async findById(id: CollectionId): Promise<Result<Collection | null>> { 50 try { 51 const collection = this.collections.get(id.getStringValue()); 52 return ok(collection ? this.clone(collection) : null); 53 } catch (error) { 54 return err(error as Error); 55 } 56 } 57 58 async findByCuratorId(curatorId: CuratorId): Promise<Result<Collection[]>> { 59 try { 60 const collections = Array.from(this.collections.values()).filter( 61 (collection) => 62 collection.authorId.value === curatorId.value || 63 collection.collaboratorIds.some((id) => id.value === curatorId.value), 64 ); 65 return ok(collections.map((collection) => this.clone(collection))); 66 } catch (error) { 67 return err(error as Error); 68 } 69 } 70 71 async findByCardId(cardId: CardId): Promise<Result<Collection[]>> { 72 try { 73 const collections = Array.from(this.collections.values()).filter( 74 (collection) => 75 collection.cardLinks.some( 76 (link) => link.cardId.getStringValue() === cardId.getStringValue(), 77 ), 78 ); 79 return ok(collections.map((collection) => this.clone(collection))); 80 } catch (error) { 81 return err(error as Error); 82 } 83 } 84 85 async findByCuratorIdContainingCard( 86 authorId: CuratorId, 87 cardId: CardId, 88 ): Promise<Result<Collection[]>> { 89 try { 90 const collections = Array.from(this.collections.values()).filter( 91 (collection) => 92 collection.authorId.value === authorId.value && 93 collection.cardLinks.some( 94 (link) => link.cardId.getStringValue() === cardId.getStringValue(), 95 ), 96 ); 97 return ok(collections.map((collection) => this.clone(collection))); 98 } catch (error) { 99 return err(error as Error); 100 } 101 } 102 103 async save(collection: Collection): Promise<Result<void>> { 104 try { 105 this.collections.set( 106 collection.collectionId.getStringValue(), 107 this.clone(collection), 108 ); 109 return ok(undefined); 110 } catch (error) { 111 return err(error as Error); 112 } 113 } 114 115 async delete(collectionId: CollectionId): Promise<Result<void>> { 116 try { 117 this.collections.delete(collectionId.getStringValue()); 118 return ok(undefined); 119 } catch (error) { 120 return err(error as Error); 121 } 122 } 123 124 // Helper methods for testing 125 public clear(): void { 126 this.collections.clear(); 127 } 128 129 public getStoredCollection(id: CollectionId): Collection | undefined { 130 return this.collections.get(id.getStringValue()); 131 } 132 133 public getAllCollections(): Collection[] { 134 return Array.from(this.collections.values()).map((collection) => 135 this.clone(collection), 136 ); 137 } 138}