feat: update aggregate implementation

This commit is contained in:
2025-08-11 13:34:28 +02:00
parent 9dddc4e79f
commit cc8c558db6
37 changed files with 361 additions and 511 deletions

View File

@@ -1,13 +1,9 @@
import { AggregateRoot } from "../../libraries/aggregate.ts";
import { AggregateFactory } from "../../libraries/aggregate-factory.ts";
import { makeId } from "../../libraries/nanoid.ts";
import { makeAggregateReducer } from "../../libraries/reducer.ts";
import { EventStoreFactory } from "./events.ts";
import { Events } from "./events.ts";
export class User extends AggregateRoot<EventStoreFactory> {
export class User extends AggregateRoot<Events> {
static override readonly name = "user";
id: string = "";
name: Name = {
given: "",
family: "",
@@ -19,40 +15,12 @@ export class User extends AggregateRoot<EventStoreFactory> {
count: 0,
};
// -------------------------------------------------------------------------
// Factories
// -------------------------------------------------------------------------
static reducer = makeAggregateReducer(User);
static create(name: Name, email: string): User {
const user = new User();
user.push({
type: "user:created",
stream: makeId(),
data: { name, email },
meta: { auditor: "foo" },
});
return user;
}
static async getById(userId: string): Promise<User | undefined> {
return this.$store.reduce({ name: "user", stream: userId, reducer: this.reducer });
}
// -------------------------------------------------------------------------
// Reducer
// -------------------------------------------------------------------------
with(event: EventStoreFactory["$events"][number]["$record"]) {
with(event: Events["$events"][number]["$record"]) {
switch (event.type) {
case "user:created": {
this.id = event.stream;
this.name.given = event.data.name?.given ?? "";
this.name.family = event.data.name?.family ?? "";
this.email = event.data.email;
break;
}
case "user:name:given-set": {
this.name.given = event.data;
break;
@@ -107,11 +75,6 @@ export class User extends AggregateRoot<EventStoreFactory> {
});
}
async snapshot(): Promise<this> {
await this.$store.createSnapshot({ name: "user", stream: this.id, reducer: User.reducer });
return this;
}
// -------------------------------------------------------------------------
// Helpers
// -------------------------------------------------------------------------
@@ -121,8 +84,6 @@ export class User extends AggregateRoot<EventStoreFactory> {
}
}
export const aggregates = new AggregateFactory([User]);
type Name = {
given: string;
family: string;

View File

@@ -1,4 +1,4 @@
import z from "zod/v4";
import z from "zod";
import { event } from "../../libraries/event.ts";
import { EventFactory } from "../../libraries/event-factory.ts";
@@ -32,4 +32,4 @@ export const events = new EventFactory([
event.type("post:removed").meta(auditor),
]);
export type EventStoreFactory = typeof events;
export type Events = typeof events;

View File

@@ -1,7 +1,7 @@
import { makeReducer } from "../../libraries/reducer.ts";
import { EventStoreFactory } from "./events.ts";
import { Events } from "./events.ts";
export const userPostReducer = makeReducer<EventStoreFactory, UserPostState>(
export const userPostReducer = makeReducer<Events, UserPostState>(
(state, event) => {
switch (event.type) {
case "post:created": {

View File

@@ -1,7 +1,7 @@
import { makeReducer } from "../../libraries/reducer.ts";
import { EventStoreFactory } from "./events.ts";
import { Events } from "./events.ts";
export const userReducer = makeReducer<EventStoreFactory, UserState>(
export const userReducer = makeReducer<Events, UserState>(
(state, event) => {
switch (event.type) {
case "user:created": {