feat: version 2 beta

This commit is contained in:
2025-04-25 22:39:47 +00:00
commit 1e58359905
75 changed files with 6899 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
import { assertEquals } from "@std/assert";
import { it } from "@std/testing/bdd";
import { nanoid } from "nanoid";
import { makeId } from "../../../libraries/nanoid.ts";
import type { EventStoreFactory } from "../mocks/events.ts";
import { userPostReducer } from "../mocks/user-posts-reducer.ts";
import { userReducer } from "../mocks/user-reducer.ts";
import { describe } from "../utilities/describe.ts";
export default describe<EventStoreFactory>(".makeReducer", (getEventStore) => {
it("should create a 'user' reducer and only reduce filtered events", async () => {
const { store } = await getEventStore();
const streamA = nanoid();
const streamB = nanoid();
await store.pushEvent(
store.event({
stream: streamA,
type: "user:created",
data: {
name: {
given: "John",
family: "Doe",
},
email: "john.doe@fixture.none",
},
meta: {
auditor: "system",
},
}),
);
await store.pushEvent(
store.event({
stream: streamB,
type: "user:created",
data: {
name: {
given: "Peter",
family: "Parker",
},
email: "peter.parker@fixture.none",
},
meta: {
auditor: "system",
},
}),
);
await store.pushEvent(
store.event({
stream: streamA,
type: "user:name:given-set",
data: "Jane",
meta: {
auditor: "system",
},
}),
);
await store.pushEvent(
store.event({
stream: streamA,
type: "user:email-set",
data: "jane.doe@fixture.none",
meta: {
auditor: "system",
},
}),
);
await store.pushEvent(
store.event({
stream: streamB,
type: "user:email-set",
data: "spiderman@fixture.none",
meta: {
auditor: "system",
},
}),
);
const state = await store.reduce({ name: "user", stream: streamA, reducer: userReducer, filter: { types: ["user:created", "user:email-set"] } });
assertEquals(state?.name, { given: "John", family: "Doe" });
assertEquals(state?.email, "jane.doe@fixture.none");
});
it("should create a 'post:count' reducer and retrieve post correct post count", async () => {
const { store, projector } = await getEventStore();
const auditor = nanoid();
projector.on("post:created", async ({ stream, meta: { auditor } }) => {
await store.relations.insert(`user:${auditor}:posts`, stream);
});
const post1 = makeId();
const post2 = makeId();
const post3 = makeId();
await store.pushEvent(store.event({ stream: post1, type: "post:created", data: { title: "Post #1", body: "Sample #1" }, meta: { auditor } }));
await store.pushEvent(store.event({ stream: post2, type: "post:created", data: { title: "Post #2", body: "Sample #2" }, meta: { auditor } }));
await store.pushEvent(store.event({ stream: post2, type: "post:removed", meta: { auditor } }));
await store.pushEvent(store.event({ stream: post3, type: "post:created", data: { title: "Post #3", body: "Sample #3" }, meta: { auditor } }));
const events = await store.getEventsByRelations([`user:${auditor}:posts`]);
assertEquals(events.length, 4);
const state = await store.reduce({ name: "user", relation: `user:${auditor}:posts`, reducer: userPostReducer });
assertEquals(state?.posts, [
{ id: post1, author: auditor },
{ id: post3, author: auditor },
]);
assertEquals(state?.count, 2);
});
});