import { SerializableEvent, VersionedAggregateRoot, } from '@task-stream/api/shared/domain'; /** * Round-trips uncommitted events like the event store does (JSON + class * prototype) and rebuilds a fresh aggregate from them. */ export function replay( aggregate: T, AggregateCls: new (id: string) => T, previous: SerializableEvent[] = [], ): { rebuilt: T; history: SerializableEvent[] } { const history = [ ...previous, ...aggregate.getUncommittedEvents().map((event, index) => ({ streamId: aggregate.id, type: event.constructor.name, position: previous.length + index + 1, data: Object.assign( Object.create(Object.getPrototypeOf(event)), JSON.parse(JSON.stringify(event)), ), })), ]; const rebuilt = new AggregateCls(aggregate.id); rebuilt.loadFromHistory(history); return { rebuilt, history }; }