import { StateReadModel } from '../Model/StateReadModel'; import { SerializerInterface } from '../../Serializer/SerializerInterface'; import { Repository } from 'ts-eventsourcing/ReadModel/Repository'; import { BlobReadModel } from 'ts-eventsourcing/ReadModel/BlobReadModel'; import { Playhead } from '../../ValueObject/Playhead'; import { Identity } from 'ts-eventsourcing/ValueObject/Identity'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; export interface SerializedStateData { playhead: Playhead; serialized: string; } export class SerializableStateRepository implements Repository, Id> { constructor(private readonly stateRepository: Repository>, private readonly serializer: SerializerInterface) { } public save(model: StateReadModel): Promise { const serialized = this.serializer.serialize(model.getState()); return this.stateRepository.save(new BlobReadModel(model.getId(), { playhead: model.getPlayhead(), serialized, })); } public has(id: Id): Promise { return this.stateRepository.has(id); } public async get(id: Id): Promise> { const model = await this.stateRepository.get(id); return this.deSerialize(model, id); } public async find(id: Id): Promise> { const data = await this.stateRepository.find(id); if (data === null) { return null; } return this.deSerialize(data, id); } public remove(id: Id): Promise { return this.stateRepository.remove(id); } public findAll(): Observable> { return this.stateRepository.findAll().pipe(map((data) => this.deSerialize(data, data.getId()))); } private deSerialize(data: BlobReadModel, id: Identity) { const payLoad = data.getPayLoad(); const deSerialized: any = this.serializer.deserialize(payLoad.serialized); return new StateReadModel(id, deSerialized, payLoad.playhead) as StateReadModel; } }