feat: add epoch event stream to aggregate id
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import type { AnyEventStore, EventsInsertSettings } from "../libraries/event-store.ts";
|
||||
import type { Unknown } from "../types/common.ts";
|
||||
import { AggregateSnapshotViolation, AggregateStreamViolation } from "./errors.ts";
|
||||
import { AggregateSnapshotViolation } from "./errors.ts";
|
||||
import { EventFactory } from "./event-factory.ts";
|
||||
|
||||
/**
|
||||
@@ -27,7 +27,7 @@ export abstract class AggregateRoot<TEventFactory extends EventFactory> {
|
||||
/**
|
||||
* Primary unique identifier for the stream the aggregate belongs to.
|
||||
*/
|
||||
#stream?: string;
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* List of pending records to push to the parent event store.
|
||||
@@ -40,6 +40,7 @@ export abstract class AggregateRoot<TEventFactory extends EventFactory> {
|
||||
* @param store - Store this aggregate instance acts against.
|
||||
*/
|
||||
constructor(store: AnyEventStore) {
|
||||
this.id = crypto.randomUUID();
|
||||
this.#store = store;
|
||||
}
|
||||
|
||||
@@ -47,20 +48,6 @@ export abstract class AggregateRoot<TEventFactory extends EventFactory> {
|
||||
// Accessors
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
set id(value: string) {
|
||||
if (this.#stream !== undefined) {
|
||||
throw new AggregateStreamViolation(this.constructor.name);
|
||||
}
|
||||
this.#stream = value;
|
||||
}
|
||||
|
||||
get id(): string {
|
||||
if (this.#stream === undefined) {
|
||||
this.#stream = crypto.randomUUID();
|
||||
}
|
||||
return this.#stream;
|
||||
}
|
||||
|
||||
get #self(): typeof AggregateRoot<TEventFactory> {
|
||||
return this.constructor as typeof AggregateRoot<TEventFactory>;
|
||||
}
|
||||
@@ -147,7 +134,7 @@ export abstract class AggregateRoot<TEventFactory extends EventFactory> {
|
||||
* any pending events, make sure to `.save()` before snapshotting.
|
||||
*/
|
||||
async snapshot() {
|
||||
const stream = this.#stream;
|
||||
const stream = this.id;
|
||||
if (stream === undefined) {
|
||||
throw new AggregateSnapshotViolation(this.#self.name);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import z, { ZodType } from "zod";
|
||||
|
||||
import { EventValidationError } from "./errors.ts";
|
||||
import { makeId } from "./nanoid.ts";
|
||||
import { getLogicalTimestamp } from "./time.ts";
|
||||
import { toPrettyErrorLines } from "./zod.ts";
|
||||
|
||||
@@ -41,8 +40,8 @@ export class Event<TEventState extends EventState = EventState> {
|
||||
const timestamp = getLogicalTimestamp();
|
||||
|
||||
const record = {
|
||||
id: makeId(),
|
||||
stream: payload.stream ?? makeId(),
|
||||
id: crypto.randomUUID(),
|
||||
stream: payload.stream ?? crypto.randomUUID(),
|
||||
type: this.state.type,
|
||||
data: "data" in payload ? payload.data : null,
|
||||
meta: "meta" in payload ? payload.meta : null,
|
||||
@@ -134,13 +133,13 @@ export type EventRecord<TEvent extends EventState = EventState> = {
|
||||
/**
|
||||
* A unique event identifier.
|
||||
*/
|
||||
id: string;
|
||||
id: UUID;
|
||||
|
||||
/**
|
||||
* Event streams are used to group related events together. This identifier
|
||||
* is used to identify the stream to which the event belongs.
|
||||
*/
|
||||
stream: string;
|
||||
stream: UUID;
|
||||
|
||||
/**
|
||||
* Type refers to the purpose of the event in a past tense descibing something
|
||||
@@ -203,3 +202,5 @@ export type EventStatus = {
|
||||
*/
|
||||
outdated: boolean;
|
||||
};
|
||||
|
||||
export type UUID = `${string}-${string}-${string}-${string}-${string}`;
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import { nanoid } from "nanoid";
|
||||
|
||||
/**
|
||||
* Generate a new nanoid.
|
||||
*
|
||||
* @param size - Size of the id. Default: 11
|
||||
*/
|
||||
export function makeId(size: number = 11): string {
|
||||
return nanoid(size);
|
||||
}
|
||||
@@ -19,6 +19,7 @@ export function makeAggregateReducer<
|
||||
},
|
||||
reduce(events: TEventFactory["$events"][number]["$record"][], snapshot?: Unknown) {
|
||||
const instance = aggregate.from(store, snapshot);
|
||||
instance.id = events[0].stream;
|
||||
for (const event of events) {
|
||||
instance.with(event);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user