From 6e703eb7eea2d57c02e92202f088250021046973 Mon Sep 17 00:00:00 2001 From: Thomas Aribart Date: Fri, 29 Sep 2023 17:47:06 +0200 Subject: [PATCH 1/5] rename storageAdapter to eventStorageAdapter everywhere --- castore.code-workspace | 2 +- .../implementation/libs/eventStores/client.ts | 2 +- .../libs/eventStores/pokemons.ts | 8 +- .../libs/eventStores/trainers.ts | 8 +- docs/docs/2-event-sourcing/3-event-stores.md | 18 +-- .../2-event-sourcing/4-fetching-events.md | 6 +- .../4-connected-event-store.md | 12 +- .../core/src/command/command.fixtures.test.ts | 6 +- .../connectedEventStore.ts | 19 ++- .../connectedEventStore.unit.test.ts | 34 ++--- packages/core/src/event/groupedEvent.ts | 9 +- ...orageAdapter.ts => eventStorageAdapter.ts} | 5 +- packages/core/src/eventStore/errors/index.ts | 2 +- .../errors/undefinedEventStorageAdapter.ts | 9 ++ .../errors/undefinedStorageAdapter.ts | 9 -- .../eventStore/eventStore.fixtures.test.ts | 6 +- packages/core/src/eventStore/eventStore.ts | 40 +++--- .../src/eventStore/eventStore.type.test.ts | 2 +- .../src/eventStore/eventStore.unit.test.ts | 20 +-- packages/core/src/eventStore/types.ts | 2 +- packages/core/src/index.ts | 6 +- .../dynamodb-event-storage-adapter/README.md | 54 ++++---- .../src/index.ts | 6 +- .../src/{adapter.ts => legacyAdapter.ts} | 56 ++++---- ...nit.test.ts => legacyAdapter.unit.test.ts} | 100 +++++++------- .../src/singleTableAdapter.ts | 56 ++++---- .../src/singleTableAdapter.unit.test.ts | 100 +++++++------- .../src/utils/formatEventForTransaction.ts | 38 ------ .../formatEventForTransaction.unit.test.ts | 44 ------ .../src/utils/pushEventsTransaction.ts | 31 ----- .../utils/pushEventsTransaction.unit.test.ts | 91 ------------- .../inmemory-event-storage-adapter/README.md | 6 +- .../src/adapter.ts | 42 +++--- .../src/adapter.unit.test.ts | 126 ++++++++++-------- .../src/command.fixtures.test.ts | 6 +- .../redux-event-storage-adapter/README.md | 4 +- .../src/adapter.ts | 36 ++--- .../src/configureCastore.ts | 2 +- .../src/errors/index.ts | 4 +- .../reduxEventStorageAdapterNotFound.ts | 2 +- ...StateNotFound.ts => reduxStateNotFound.ts} | 2 +- .../src/hooks/useAggregateEvents.ts | 14 +- .../src/hooks/useAggregateIds.ts | 14 +- packages/test-tools/README.md | 4 +- .../src/mockEventStore.unit.test.ts | 2 +- packages/test-tools/src/mockedEventStore.ts | 8 +- packages/test-tools/src/muteEventStore.ts | 6 +- .../src/muteEventStore.unit.test.ts | 2 +- 48 files changed, 444 insertions(+), 637 deletions(-) rename packages/core/src/{storageAdapter.ts => eventStorageAdapter.ts} (95%) create mode 100644 packages/core/src/eventStore/errors/undefinedEventStorageAdapter.ts delete mode 100644 packages/core/src/eventStore/errors/undefinedStorageAdapter.ts rename packages/dynamodb-event-storage-adapter/src/{adapter.ts => legacyAdapter.ts} (89%) rename packages/dynamodb-event-storage-adapter/src/{adapter.unit.test.ts => legacyAdapter.unit.test.ts} (84%) delete mode 100644 packages/dynamodb-event-storage-adapter/src/utils/formatEventForTransaction.ts delete mode 100644 packages/dynamodb-event-storage-adapter/src/utils/formatEventForTransaction.unit.test.ts delete mode 100644 packages/dynamodb-event-storage-adapter/src/utils/pushEventsTransaction.ts delete mode 100644 packages/dynamodb-event-storage-adapter/src/utils/pushEventsTransaction.unit.test.ts rename packages/redux-event-storage-adapter/src/errors/{eventStoreReduxStateNotFound.ts => reduxStateNotFound.ts} (79%) diff --git a/castore.code-workspace b/castore.code-workspace index c2a41d8c..0c445627 100644 --- a/castore.code-workspace +++ b/castore.code-workspace @@ -39,7 +39,7 @@ }, { "path": "packages/dynamodb-event-storage-adapter", - "name": "🔌 DynamoDb" + "name": "🔌 DynamoDB" }, { "path": "packages/redux-event-storage-adapter", diff --git a/demo/implementation/libs/eventStores/client.ts b/demo/implementation/libs/eventStores/client.ts index 15677c78..f2d59f93 100644 --- a/demo/implementation/libs/eventStores/client.ts +++ b/demo/implementation/libs/eventStores/client.ts @@ -1,3 +1,3 @@ import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; -export const dynamoDbClient = new DynamoDBClient({}); +export const dynamoDBClient = new DynamoDBClient({}); diff --git a/demo/implementation/libs/eventStores/pokemons.ts b/demo/implementation/libs/eventStores/pokemons.ts index 67d05b46..114f623d 100644 --- a/demo/implementation/libs/eventStores/pokemons.ts +++ b/demo/implementation/libs/eventStores/pokemons.ts @@ -1,11 +1,11 @@ import { pokemonsEventStore as $pokemonsEventStore } from '@castore/demo-blueprint'; -import { DynamoDbEventStorageAdapter } from '@castore/dynamodb-event-storage-adapter'; +import { LegacyDynamoDBEventStorageAdapter } from '@castore/dynamodb-event-storage-adapter'; -import { dynamoDbClient } from './client'; +import { dynamoDBClient } from './client'; export const pokemonsEventStore = $pokemonsEventStore; -pokemonsEventStore.storageAdapter = new DynamoDbEventStorageAdapter({ +pokemonsEventStore.eventStorageAdapter = new LegacyDynamoDBEventStorageAdapter({ tableName: process.env.POKEMON_EVENTS_TABLE_NAME as string, - dynamoDbClient, + dynamoDBClient, }); diff --git a/demo/implementation/libs/eventStores/trainers.ts b/demo/implementation/libs/eventStores/trainers.ts index 313226a6..61941a4d 100644 --- a/demo/implementation/libs/eventStores/trainers.ts +++ b/demo/implementation/libs/eventStores/trainers.ts @@ -1,11 +1,11 @@ import { trainersEventStore as $trainersEventStore } from '@castore/demo-blueprint'; -import { DynamoDbEventStorageAdapter } from '@castore/dynamodb-event-storage-adapter'; +import { LegacyDynamoDBEventStorageAdapter } from '@castore/dynamodb-event-storage-adapter'; -import { dynamoDbClient } from './client'; +import { dynamoDBClient } from './client'; export const trainersEventStore = $trainersEventStore; -trainersEventStore.storageAdapter = new DynamoDbEventStorageAdapter({ +trainersEventStore.eventStorageAdapter = new LegacyDynamoDBEventStorageAdapter({ tableName: process.env.TRAINER_EVENTS_TABLE_NAME as string, - dynamoDbClient, + dynamoDBClient, }); diff --git a/docs/docs/2-event-sourcing/3-event-stores.md b/docs/docs/2-event-sourcing/3-event-stores.md index 81e646d2..25cb18d9 100644 --- a/docs/docs/2-event-sourcing/3-event-stores.md +++ b/docs/docs/2-event-sourcing/3-event-stores.md @@ -54,7 +54,7 @@ const pokemonsEventStore = new EventStore({ - eventStoreEvents (EventType[]): The list of event types in the event store - reduce (EventType[]): A reducer function that can be applied to the store event types - onEventPushed (?(pushEventResponse: PushEventResponse) => Promise<void>): To run a callback after events are pushed (input is exactly the return value of the pushEvent method) -- storageAdapter (?EventStorageAdapter): See fetching events +- eventStorageAdapter (?EventStorageAdapter): See fetching events > ☝️ The return type of the `reducer` is used to infer the `Aggregate` type of the `EventStore`, so it is important to type it explicitely. @@ -90,26 +90,26 @@ const onEventPushed = pokemonsEventStore.onEventPushed; // => undefined (we did not provide one in this example) ``` -- storageAdapter (?EventStorageAdapter): See fetching events +- eventStorageAdapter (?EventStorageAdapter): See fetching events ```ts -const storageAdapter = pokemonsEventStore.storageAdapter; +const eventStorageAdapter = pokemonsEventStore.eventStorageAdapter; // => undefined (we did not provide one in this example) ``` -> ☝️ The `storageAdapter` is not read-only so you do not have to provide it right away. +> ☝️ The `eventStorageAdapter` is not read-only so you do not have to provide it right away. --- **Sync Methods:** -- getStorageAdapter (() => EventStorageAdapter): Returns the event store event storage adapter if it exists. Throws an UndefinedStorageAdapterError if it doesn't. +- getEventStorageAdapter (() => EventStorageAdapter): Returns the event store event storage adapter if it exists. Throws an UndefinedEventStorageAdapterError if it doesn't. ```ts -import { UndefinedStorageAdapterError } from '@castore/core'; +import { UndefinedEventStorageAdapterError } from '@castore/core'; -expect(() => pokemonsEventStore.getStorageAdapter()).toThrow( - new UndefinedStorageAdapterError({ eventStoreId: 'POKEMONS' }), +expect(() => pokemonsEventStore.getEventStorageAdapter()).toThrow( + new UndefinedEventStorageAdapterError({ eventStoreId: 'POKEMONS' }), ); // => true ``` @@ -126,7 +126,7 @@ const myPikachuAggregate = pokemonsEventStore.buildAggregate(myPikachuEvents); **Async Methods:** -The following methods interact with the data layer of your event store through its [`EventStorageAdapter`](./4-fetching-events.md). They will throw an `UndefinedStorageAdapterError` if you did not provide one. +The following methods interact with the data layer of your event store through its [`EventStorageAdapter`](./4-fetching-events.md). They will throw an `UndefinedEventStorageAdapterError` if you did not provide one. - getEvents ((aggregateId: string, opt?: OptionsObj) => Promise<ResponseObj>): Retrieves the events of an aggregate, ordered by version. Returns an empty array if no event is found for this aggregateId. diff --git a/docs/docs/2-event-sourcing/4-fetching-events.md b/docs/docs/2-event-sourcing/4-fetching-events.md index 0f75bc53..417f9b77 100644 --- a/docs/docs/2-event-sourcing/4-fetching-events.md +++ b/docs/docs/2-event-sourcing/4-fetching-events.md @@ -10,18 +10,18 @@ For the moment, we didn't provide any actual way to store our events data. This import { EventStore } from '@castore/core'; await pokemonsEventStore.getEvents('pikachu1'); -// ❌ Will throw an `UndefinedStorageAdapterError` +// ❌ Will throw an `UndefinedEventStorageAdapterError` const pokemonsEventStore = new EventStore({ eventStoreId: 'POKEMONS', eventTypes: pokemonEventTypes, reduce: pokemonsReducer, // 👇 Provide it in the constructor - storageAdapter: mySuperStorageAdapter, + eventStorageAdapter: mySuperEventStorageAdapter, }); // 👇 ...or set/switch it in context later -pokemonsEventStore.storageAdapter = mySuperStorageAdapter; +pokemonsEventStore.eventStorageAdapter = mySuperEventStorageAdapter; const { events } = await pokemonsEventStore.getEvents('pikachu1'); const { aggregate } = await pokemonsEventStore.getAggregate('pikachu1'); diff --git a/docs/docs/3-reacting-to-events/4-connected-event-store.md b/docs/docs/3-reacting-to-events/4-connected-event-store.md index 58315da1..a7e8acac 100644 --- a/docs/docs/3-reacting-to-events/4-connected-event-store.md +++ b/docs/docs/3-reacting-to-events/4-connected-event-store.md @@ -30,7 +30,7 @@ await connectedPokemonsEventStore.pushEvent({ :::info -Note that setting a connected event store `storageAdapter` and `onEventPushed` properties will override those of the original event store instead. +Note that setting a connected event store `eventStorageAdapter` and `onEventPushed` properties will override those of the original event store instead. ::: @@ -81,14 +81,14 @@ const messageChannel = connectedPokemonsEventStore.messageChannel; // => appMessageBus ``` -> ☝️ Note that the `storageAdapter` property will act as a pointer toward the original event store `storageAdapter`: +> ☝️ Note that the `eventStorageAdapter` property will act as a pointer toward the original event store `eventStorageAdapter`: > > ```ts -> originalEventStore.storageAdapter = myStorageAdapter; -> connectedEventStore.storageAdapter; // => myStorageAdapter +> originalEventStore.eventStorageAdapter = myEventStorageAdapter; +> connectedEventStore.eventStorageAdapter; // => myEventStorageAdapter > -> connectedEventStore.storageAdapter = anotherStorageAdapter; -> originalEventStore.storageAdapter; // => anotherStorageAdapter +> connectedEventStore.eventStorageAdapter = anotherEventStorageAdapter; +> originalEventStore.eventStorageAdapter; // => anotherEventStorageAdapter > ``` diff --git a/packages/core/src/command/command.fixtures.test.ts b/packages/core/src/command/command.fixtures.test.ts index 6fe8b08d..d0ff37eb 100644 --- a/packages/core/src/command/command.fixtures.test.ts +++ b/packages/core/src/command/command.fixtures.test.ts @@ -1,12 +1,12 @@ import { vi } from 'vitest'; import { EventType, EventTypeDetail } from '~/event/eventType'; +import { EventStorageAdapter } from '~/eventStorageAdapter'; import { eventAlreadyExistsErrorCode, EventAlreadyExistsError, EventStore, } from '~/eventStore'; -import { StorageAdapter } from '~/storageAdapter'; import { tuple, Command } from './command'; @@ -19,7 +19,7 @@ export const putSnapshotMock = vi.fn(); export const getLastSnapshotMock = vi.fn(); export const listSnapshotsMock = vi.fn(); -export const mockStorageAdapter: StorageAdapter = { +export const eventStorageAdapterMock: EventStorageAdapter = { pushEvent: pushEventMock, pushEventGroup: pushEventGroupMock, groupEvent: groupEventMock, @@ -116,7 +116,7 @@ export const counterEventStore = new EventStore({ counterDeletedEvent, ], reduce: countersReducer, - storageAdapter: mockStorageAdapter, + eventStorageAdapter: eventStorageAdapterMock, }); export const requiredEventStores = tuple(counterEventStore); diff --git a/packages/core/src/connectedEventStore/connectedEventStore.ts b/packages/core/src/connectedEventStore/connectedEventStore.ts index 630f7375..dbe64df5 100644 --- a/packages/core/src/connectedEventStore/connectedEventStore.ts +++ b/packages/core/src/connectedEventStore/connectedEventStore.ts @@ -1,6 +1,7 @@ import type { Aggregate } from '~/aggregate'; import type { EventDetail } from '~/event/eventDetail'; import type { EventType, EventTypesDetails } from '~/event/eventType'; +import type { EventStorageAdapter } from '~/eventStorageAdapter'; import type { Reducer, AggregateIdsLister, @@ -14,7 +15,6 @@ import type { OnEventPushed, } from '~/eventStore'; import type { EventStoreMessageChannel } from '~/messaging'; -import type { StorageAdapter } from '~/storageAdapter'; import type { $Contravariant } from '~/utils'; import { publishPushedEvent } from './publishPushedEvent'; @@ -87,7 +87,7 @@ export class ConnectedEventStore< getAggregate: AggregateGetter; getExistingAggregate: AggregateGetter; simulateAggregate: AggregateSimulator<$EVENT_DETAIL, AGGREGATE>; - getStorageAdapter: () => StorageAdapter; + getEventStorageAdapter: () => EventStorageAdapter; eventStore: EventStore< EVENT_STORE_ID, @@ -123,7 +123,7 @@ export class ConnectedEventStore< this.getAggregate = eventStore.getAggregate; this.getExistingAggregate = eventStore.getExistingAggregate; this.simulateAggregate = eventStore.simulateAggregate; - this.getStorageAdapter = eventStore.getStorageAdapter; + this.getEventStorageAdapter = eventStore.getEventStorageAdapter; this.pushEvent = async (eventInput, options = {}) => { const response = await this.eventStore.pushEvent(eventInput, options); @@ -137,15 +137,14 @@ export class ConnectedEventStore< this.messageChannel = messageChannel; } - /** - * @debt v2 "rename as eventStorageAdapter" - */ - set storageAdapter(storageAdapter: StorageAdapter | undefined) { - this.eventStore.storageAdapter = storageAdapter; + set eventStorageAdapter( + eventStorageAdapter: EventStorageAdapter | undefined, + ) { + this.eventStore.eventStorageAdapter = eventStorageAdapter; } - get storageAdapter(): StorageAdapter | undefined { - return this.eventStore.storageAdapter; + get eventStorageAdapter(): EventStorageAdapter | undefined { + return this.eventStore.eventStorageAdapter; } set onEventPushed( diff --git a/packages/core/src/connectedEventStore/connectedEventStore.unit.test.ts b/packages/core/src/connectedEventStore/connectedEventStore.unit.test.ts index acbc7ef1..40376405 100644 --- a/packages/core/src/connectedEventStore/connectedEventStore.unit.test.ts +++ b/packages/core/src/connectedEventStore/connectedEventStore.unit.test.ts @@ -1,17 +1,17 @@ import { vi } from 'vitest'; import { GroupedEvent } from '~/event/groupedEvent'; +import type { EventStorageAdapter } from '~/eventStorageAdapter'; import { EventStore } from '~/eventStore/eventStore'; import { pokemonsEventStore, - storageAdapterMock, + eventStorageAdapterMock, pikachuAppearedEvent, pikachuLeveledUpEvent, pikachuCaughtEvent, pushEventGroupMock, PokemonEventDetails, } from '~/eventStore/eventStore.fixtures.test'; -import { StorageAdapter } from '~/storageAdapter'; import { pokemonsEventStoreWithNotificationMessageQueue, @@ -25,7 +25,7 @@ const publishPushedEventMock = vi const pushEvent = vi.spyOn(pokemonsEventStore, 'pushEvent'); -export const anotherStorageAdapterMock: StorageAdapter = { +export const anotherEventStorageAdapterMock: EventStorageAdapter = { pushEvent: vi.fn(), pushEventGroup: vi.fn(), groupEvent: vi.fn(), @@ -123,12 +123,12 @@ describe('ConnectedEventStore', () => { event: pikachuCaughtEvent, prevAggregate: prevPikachuAggregate, eventStore: pokemonsEventStoreWithStateCarryingMessageBus, - eventStorageAdapter: storageAdapterMock, + eventStorageAdapter: eventStorageAdapterMock, }), new GroupedEvent({ event: charizardLeveledUpEvent, eventStore: pokemonsEventStoreWithNotificationMessageQueue, - eventStorageAdapter: storageAdapterMock, + eventStorageAdapter: eventStorageAdapterMock, }), ] as const; @@ -153,20 +153,24 @@ describe('ConnectedEventStore', () => { }); }); - describe('storageAdapter', () => { + describe('eventStorageAdapterMock', () => { it('sets & gets the original event storage adapter', () => { - pokemonsEventStoreWithNotificationMessageQueue.storageAdapter = - anotherStorageAdapterMock; + pokemonsEventStoreWithNotificationMessageQueue.eventStorageAdapter = + anotherEventStorageAdapterMock; expect( - pokemonsEventStoreWithNotificationMessageQueue.storageAdapter, - ).toBe(anotherStorageAdapterMock); - expect(pokemonsEventStore.storageAdapter).toBe(anotherStorageAdapterMock); + pokemonsEventStoreWithNotificationMessageQueue.eventStorageAdapter, + ).toBe(anotherEventStorageAdapterMock); + expect(pokemonsEventStore.eventStorageAdapter).toBe( + anotherEventStorageAdapterMock, + ); - pokemonsEventStore.storageAdapter = storageAdapterMock; + pokemonsEventStore.eventStorageAdapter = eventStorageAdapterMock; expect( - pokemonsEventStoreWithNotificationMessageQueue.storageAdapter, - ).toBe(storageAdapterMock); - expect(pokemonsEventStore.storageAdapter).toBe(storageAdapterMock); + pokemonsEventStoreWithNotificationMessageQueue.eventStorageAdapter, + ).toBe(eventStorageAdapterMock); + expect(pokemonsEventStore.eventStorageAdapter).toBe( + eventStorageAdapterMock, + ); }); }); }); diff --git a/packages/core/src/event/groupedEvent.ts b/packages/core/src/event/groupedEvent.ts index b09dbc6c..95d9417c 100644 --- a/packages/core/src/event/groupedEvent.ts +++ b/packages/core/src/event/groupedEvent.ts @@ -1,6 +1,9 @@ import type { Aggregate } from '~/aggregate'; +import type { + EventStorageAdapter, + EventStoreContext, +} from '~/eventStorageAdapter'; import type { EventStore } from '~/eventStore/eventStore'; -import type { StorageAdapter, EventStoreContext } from '~/storageAdapter'; import type { EventDetail, OptionalTimestamp } from './eventDetail'; @@ -16,7 +19,7 @@ export class GroupedEvent< context?: EventStoreContext; prevAggregate?: AGGREGATE; - eventStorageAdapter: StorageAdapter; + eventStorageAdapter: EventStorageAdapter; eventStore?: EventStore; constructor({ @@ -30,7 +33,7 @@ export class GroupedEvent< context?: EventStoreContext; prevAggregate?: AGGREGATE; eventStore?: EventStore; - eventStorageAdapter: StorageAdapter; + eventStorageAdapter: EventStorageAdapter; }) { this.event = event; if (context !== undefined) { diff --git a/packages/core/src/storageAdapter.ts b/packages/core/src/eventStorageAdapter.ts similarity index 95% rename from packages/core/src/storageAdapter.ts rename to packages/core/src/eventStorageAdapter.ts index ba767944..8b6f819c 100644 --- a/packages/core/src/storageAdapter.ts +++ b/packages/core/src/eventStorageAdapter.ts @@ -39,10 +39,7 @@ export type ListSnapshotsOptions = { reverse?: boolean; }; -/** - * @debt v2 "To rename EventStorageAdapter" - */ -export interface StorageAdapter { +export interface EventStorageAdapter { getEvents: ( aggregateId: string, context: EventStoreContext, diff --git a/packages/core/src/eventStore/errors/index.ts b/packages/core/src/eventStore/errors/index.ts index 56d01db3..e6223a9a 100644 --- a/packages/core/src/eventStore/errors/index.ts +++ b/packages/core/src/eventStore/errors/index.ts @@ -1,3 +1,3 @@ export * from './aggregateNotFound'; export * from './eventAlreadyExists'; -export * from './undefinedStorageAdapter'; +export * from './undefinedEventStorageAdapter'; diff --git a/packages/core/src/eventStore/errors/undefinedEventStorageAdapter.ts b/packages/core/src/eventStore/errors/undefinedEventStorageAdapter.ts new file mode 100644 index 00000000..c068fcd2 --- /dev/null +++ b/packages/core/src/eventStore/errors/undefinedEventStorageAdapter.ts @@ -0,0 +1,9 @@ +export class UndefinedEventStorageAdapterError extends Error { + eventStoreId: string; + + constructor({ eventStoreId }: { eventStoreId: string }) { + super(`EventStorageAdapter not found for event store ${eventStoreId}`); + + this.eventStoreId = eventStoreId; + } +} diff --git a/packages/core/src/eventStore/errors/undefinedStorageAdapter.ts b/packages/core/src/eventStore/errors/undefinedStorageAdapter.ts deleted file mode 100644 index 1e85d38f..00000000 --- a/packages/core/src/eventStore/errors/undefinedStorageAdapter.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class UndefinedStorageAdapterError extends Error { - eventStoreId: string; - - constructor({ eventStoreId }: { eventStoreId: string }) { - super(`Storage Adapter undefined for event store ${eventStoreId} `); - - this.eventStoreId = eventStoreId; - } -} diff --git a/packages/core/src/eventStore/eventStore.fixtures.test.ts b/packages/core/src/eventStore/eventStore.fixtures.test.ts index 5fd49276..a6a93230 100644 --- a/packages/core/src/eventStore/eventStore.fixtures.test.ts +++ b/packages/core/src/eventStore/eventStore.fixtures.test.ts @@ -2,8 +2,8 @@ import { vi } from 'vitest'; import { EventType, EventTypeDetail } from '~/event/eventType'; +import { EventStorageAdapter } from '~/eventStorageAdapter'; import { EventStore } from '~/eventStore'; -import { StorageAdapter } from '~/storageAdapter'; export const pushEventMock = vi.fn(); export const pushEventGroupMock = vi.fn(); @@ -14,7 +14,7 @@ export const putSnapshotMock = vi.fn(); export const getLastSnapshotMock = vi.fn(); export const listSnapshotsMock = vi.fn(); -export const storageAdapterMock: StorageAdapter = { +export const eventStorageAdapterMock: EventStorageAdapter = { pushEvent: pushEventMock, pushEventGroup: pushEventGroupMock, groupEvent: groupEventMock, @@ -120,5 +120,5 @@ export const pokemonsEventStore = new EventStore({ pokemonLeveledUpEvent, ], reduce: pokemonsReducer, - storageAdapter: storageAdapterMock, + eventStorageAdapter: eventStorageAdapterMock, }); diff --git a/packages/core/src/eventStore/eventStore.ts b/packages/core/src/eventStore/eventStore.ts index a580ceaf..08224fb1 100644 --- a/packages/core/src/eventStore/eventStore.ts +++ b/packages/core/src/eventStore/eventStore.ts @@ -3,11 +3,11 @@ import type { Aggregate } from '~/aggregate'; import type { EventDetail } from '~/event/eventDetail'; import type { EventType, EventTypesDetails } from '~/event/eventType'; import type { GroupedEvent } from '~/event/groupedEvent'; -import type { StorageAdapter } from '~/storageAdapter'; +import type { EventStorageAdapter } from '~/eventStorageAdapter'; import type { $Contravariant } from '~/utils'; import { AggregateNotFoundError } from './errors/aggregateNotFound'; -import { UndefinedStorageAdapterError } from './errors/undefinedStorageAdapter'; +import { UndefinedEventStorageAdapterError } from './errors/undefinedEventStorageAdapter'; import type { AggregateIdsLister, EventPusher, @@ -119,11 +119,8 @@ export class EventStore< getAggregate: AggregateGetter; getExistingAggregate: AggregateGetter; simulateAggregate: AggregateSimulator<$EVENT_DETAILS, AGGREGATE>; - /** - * @debt v2 "rename as eventStorageAdapter" - */ - storageAdapter?: StorageAdapter; - getStorageAdapter: () => StorageAdapter; + eventStorageAdapter?: EventStorageAdapter; + getEventStorageAdapter: () => EventStorageAdapter; constructor({ eventStoreId, @@ -133,7 +130,7 @@ export class EventStore< ...indexedEvents, [event.version]: event, }), - storageAdapter: $storageAdapter, + eventStorageAdapter: $eventStorageAdapter, }: { eventStoreId: EVENT_STORE_ID; /** @@ -145,29 +142,26 @@ export class EventStore< */ reduce: REDUCER; simulateSideEffect?: SideEffectsSimulator; - storageAdapter?: StorageAdapter; + eventStorageAdapter?: EventStorageAdapter; }) { this.eventStoreId = eventStoreId; this.eventStoreEvents = eventStoreEvents; this.reduce = reduce; this.simulateSideEffect = simulateSideEffect; - /** - * @debt v2 "rename as eventStorageAdapter" - */ - this.storageAdapter = $storageAdapter; + this.eventStorageAdapter = $eventStorageAdapter; - this.getStorageAdapter = () => { - if (!this.storageAdapter) { - throw new UndefinedStorageAdapterError({ + this.getEventStorageAdapter = () => { + if (!this.eventStorageAdapter) { + throw new UndefinedEventStorageAdapterError({ eventStoreId: this.eventStoreId, }); } - return this.storageAdapter; + return this.eventStorageAdapter; }; this.getEvents = (aggregateId, queryOptions) => - this.getStorageAdapter().getEvents( + this.getEventStorageAdapter().getEvents( aggregateId, { eventStoreId: this.eventStoreId }, queryOptions, @@ -180,9 +174,9 @@ export class EventStore< eventDetail, { prevAggregate, force = false } = {}, ) => { - const storageAdapter = this.getStorageAdapter(); + const eventStorageAdapter = this.getEventStorageAdapter(); - const { event } = (await storageAdapter.pushEvent(eventDetail, { + const { event } = (await eventStorageAdapter.pushEvent(eventDetail, { eventStoreId: this.eventStoreId, force, })) as { event: $EVENT_DETAILS }; @@ -210,9 +204,9 @@ export class EventStore< }; this.groupEvent = (eventDetail, { prevAggregate } = {}) => { - const storageAdapter = this.getStorageAdapter(); + const eventStorageAdapter = this.getEventStorageAdapter(); - const groupedEvent = storageAdapter.groupEvent( + const groupedEvent = eventStorageAdapter.groupEvent( eventDetail, ) as GroupedEvent; @@ -227,7 +221,7 @@ export class EventStore< }; this.listAggregateIds = options => - this.getStorageAdapter().listAggregateIds( + this.getEventStorageAdapter().listAggregateIds( { eventStoreId: this.eventStoreId }, options, ); diff --git a/packages/core/src/eventStore/eventStore.type.test.ts b/packages/core/src/eventStore/eventStore.type.test.ts index 770ef642..01a1a3d4 100644 --- a/packages/core/src/eventStore/eventStore.type.test.ts +++ b/packages/core/src/eventStore/eventStore.type.test.ts @@ -4,13 +4,13 @@ import type { Aggregate } from '~/aggregate'; import type { EventDetail, OptionalTimestamp } from '~/event/eventDetail'; import type { EventTypeDetail } from '~/event/eventType'; import type { GroupedEvent } from '~/event/groupedEvent'; +import type { EventsQueryOptions } from '~/eventStorageAdapter'; import { EventStore, EventStoreAggregate, EventStoreEventsDetails, GetAggregateOptions, } from '~/eventStore'; -import type { EventsQueryOptions } from '~/storageAdapter'; import { pokemonsEventStore, diff --git a/packages/core/src/eventStore/eventStore.unit.test.ts b/packages/core/src/eventStore/eventStore.unit.test.ts index 9efe0d07..d7a066e5 100644 --- a/packages/core/src/eventStore/eventStore.unit.test.ts +++ b/packages/core/src/eventStore/eventStore.unit.test.ts @@ -22,7 +22,7 @@ import { getLastSnapshotMock, putSnapshotMock, groupEventMock, - storageAdapterMock, + eventStorageAdapterMock, PokemonEventDetails, } from './eventStore.fixtures.test'; @@ -45,8 +45,8 @@ describe('event store', () => { 'eventStoreEvents', 'reduce', 'simulateSideEffect', - 'storageAdapter', - 'getStorageAdapter', + 'eventStorageAdapter', + 'getEventStorageAdapter', 'pushEvent', 'groupEvent', 'buildAggregate', @@ -194,7 +194,7 @@ describe('event store', () => { groupEventMock.mockReturnValue( new GroupedEvent({ event: pikachuLeveledUpEvent, - eventStorageAdapter: storageAdapterMock, + eventStorageAdapter: eventStorageAdapterMock, }), ); @@ -245,11 +245,11 @@ describe('event store', () => { const eventGroup = [ new GroupedEvent({ event: pikachuLeveledUpEvent, - eventStorageAdapter: storageAdapterMock, + eventStorageAdapter: eventStorageAdapterMock, }), new GroupedEvent({ event: charizardLeveledUpEvent, - eventStorageAdapter: storageAdapterMock, + eventStorageAdapter: eventStorageAdapterMock, }), ] as const; @@ -278,11 +278,11 @@ describe('event store', () => { new GroupedEvent({ event: pikachuLeveledUpEvent, eventStore: pokemonsEventStore, - eventStorageAdapter: storageAdapterMock, + eventStorageAdapter: eventStorageAdapterMock, }), new GroupedEvent({ event: charizardLeveledUpEvent, - eventStorageAdapter: storageAdapterMock, + eventStorageAdapter: eventStorageAdapterMock, }), ] as const; @@ -308,11 +308,11 @@ describe('event store', () => { pikachuAppearedEvent, ]), eventStore: pokemonsEventStore, - eventStorageAdapter: storageAdapterMock, + eventStorageAdapter: eventStorageAdapterMock, }), new GroupedEvent({ event: charizardLeveledUpEvent, - eventStorageAdapter: storageAdapterMock, + eventStorageAdapter: eventStorageAdapterMock, }), ] as const; diff --git a/packages/core/src/eventStore/types.ts b/packages/core/src/eventStore/types.ts index 90bdbb7a..499366b4 100644 --- a/packages/core/src/eventStore/types.ts +++ b/packages/core/src/eventStore/types.ts @@ -5,7 +5,7 @@ import type { EventsQueryOptions, ListAggregateIdsOptions, ListAggregateIdsOutput, -} from '~/storageAdapter'; +} from '~/eventStorageAdapter'; import type { $Contravariant } from '~/utils'; export type Reducer< diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 04026d94..d0e494c8 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -3,14 +3,14 @@ export { EventType } from './event/eventType'; export type { EventTypeDetail, EventTypesDetails } from './event/eventType'; export { GroupedEvent } from './event/groupedEvent'; export type { EventDetail, OptionalTimestamp } from './event/eventDetail'; -export type { StorageAdapter } from './storageAdapter'; +export type { EventStorageAdapter } from './eventStorageAdapter'; export type { EventsQueryOptions, PushEventOptions, EventStoreContext, ListAggregateIdsOptions, ListAggregateIdsOutput, -} from './storageAdapter'; +} from './eventStorageAdapter'; export { AggregateNotFoundError, isEventAlreadyExistsError, @@ -19,7 +19,7 @@ export { } from './eventStore'; export type { EventAlreadyExistsError, - UndefinedStorageAdapterError, + UndefinedEventStorageAdapterError, GetAggregateOptions, SimulationOptions, EventStoreId, diff --git a/packages/dynamodb-event-storage-adapter/README.md b/packages/dynamodb-event-storage-adapter/README.md index 8226f747..5a7f9cd5 100644 --- a/packages/dynamodb-event-storage-adapter/README.md +++ b/packages/dynamodb-event-storage-adapter/README.md @@ -26,14 +26,14 @@ yarn add @castore/core @aws-sdk/client-dynamodb This library exposes two adapters: -- `DynamoDbSingleTableEventStorageAdapter` which can plug several event stores to a single DynamoDB table. -- (_deprecated_) `DynamoDbEventStorageAdapter` which needs a DynamoDB table per event store. +- `DynamoDBSingleTableEventStorageAdapter` which can plug several event stores to a single DynamoDB table. +- (_deprecated_) `DynamoDBEventStorageAdapter` which needs a DynamoDB table per event store. -The legacy `DynamoDbEventStorageAdapter` is still exposed for backward compatibility. It will be deprecated and renamed `LegacyDynamoDbEventStorageAdapter` in the v2, to be finally removed in the v3. +The legacy `DynamoDBEventStorageAdapter` is still exposed for backward compatibility. It will be deprecated and renamed `LegacyDynamoDBEventStorageAdapter` in the v2, to be finally removed in the v3. Documentation: -- [`DynamoDbSingleTableEventStorageAdapter`](#dynamodbsingletableeventstorageadapter) +- [`DynamoDBSingleTableEventStorageAdapter`](#dynamodbsingletableeventstorageadapter) - [👩‍💻 Usage](#-usage) - [🤔 How it works](#-how-it-works) - [📝 Examples](#-examples) @@ -43,36 +43,36 @@ Documentation: - [🤝 EventGroups](#-eventgroups) - [🔑 IAM](#-iam) - [📸 `ImageParser`](#-imageparser) -- [`DynamoDbEventStorageAdapter`](#legacy-dynamodbeventstorageadapter) +- [`DynamoDBEventStorageAdapter`](#legacy-dynamodbeventstorageadapter) -## `DynamoDbSingleTableEventStorageAdapter` +## `DynamoDBSingleTableEventStorageAdapter` ### 👩‍💻 Usage ```ts import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; -import { DynamoDbSingleTableEventStorageAdapter } from '@castore/dynamodb-event-storage-adapter'; +import { DynamoDBSingleTableEventStorageAdapter } from '@castore/dynamodb-event-storage-adapter'; -const dynamoDbClient = new DynamoDBClient({}); +const dynamoDBClient = new DynamoDBClient({}); -const pokemonsEventsStorageAdapter = new DynamoDbSingleTableEventStorageAdapter( +const pokemonsEventStorageAdapter = new DynamoDBSingleTableEventStorageAdapter( { tableName: 'my-table-name', - dynamoDbClient, + dynamoDBClient, }, ); // 👇 Alternatively, provide a getter -const pokemonsEventsStorageAdapter = - new DynamoDbSingleTableEventStorageAdapter({ +const pokemonsEventStorageAdapter = + new DynamoDBSingleTableEventStorageAdapter({ tableName: () => process.env.MY_TABLE_NAME, - dynamoDbClient, + dynamoDBClient, }); const pokemonsEventStore = new EventStore({ ... - storageAdapter: pokemonsEventsStorageAdapter, + eventStorageAdapter: pokemonsEventStorageAdapter, }); ``` @@ -227,7 +227,7 @@ resource "aws_dynamodb_table" "pokemons-events-table" { ### 🤝 EventGroups -This adapter implements the [EventGroups](https://github.com/castore-dev/castore/#event-groups) API using the [DynamoDb Transactions API](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html): +This adapter implements the [EventGroups](https://github.com/castore-dev/castore/#event-groups) API using the [DynamoDB Transactions API](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html): ```ts import { EventStore } from '@castore/core'; @@ -244,7 +244,7 @@ await EventStore.pushEventGroup( Note that: -- All the event stores involved in the transaction need to use the `DynamoDbSingleTableEventStorageAdapter` +- All the event stores involved in the transaction need to use the `DynamoDBSingleTableEventStorageAdapter` - This util inherits of the [`TransactWriteItem` API](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txwriteitems) limitations: It can target up to 100 distinct events in one or more DynamoDB tables within the same AWS account and in the same Region. ### 🔑 IAM @@ -257,7 +257,7 @@ Required IAM permissions for each operations: ### 📸 `ImageParser` -This library also exposes a useful `ImageParser` class to parse [DynamoDB stream](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html) images from a `DynamoDbSingleTableEventStorageAdapter`. It will build a correctly typed `NotificationMessage` ouf of a stream image, unmarshalling it, removing the prefix of the `aggregateId` in the process and validating the `eventStoreId`: +This library also exposes a useful `ImageParser` class to parse [DynamoDB stream](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html) images from a `DynamoDBSingleTableEventStorageAdapter`. It will build a correctly typed `NotificationMessage` ouf of a stream image, unmarshalling it, removing the prefix of the `aggregateId` in the process and validating the `eventStoreId`: ```ts import { ImageParser } from '@castore/dynamodb-event-storage-adapter'; @@ -277,7 +277,7 @@ const notificationMessage = imageParser.parseImage( ); ``` -## Legacy `DynamoDbEventStorageAdapter` +## Legacy `DynamoDBEventStorageAdapter`
🔧 Documentation @@ -287,24 +287,24 @@ const notificationMessage = imageParser.parseImage( ```ts import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; -import { DynamoDbEventStorageAdapter } from '@castore/dynamodb-event-storage-adapter'; +import { DynamoDBEventStorageAdapter } from '@castore/dynamodb-event-storage-adapter'; -const dynamoDbClient = new DynamoDBClient({}); +const dynamoDBClient = new DynamoDBClient({}); -const pokemonsEventsStorageAdapter = new DynamoDbEventStorageAdapter({ +const pokemonsEventStorageAdapter = new DynamoDBEventStorageAdapter({ tableName: 'my-table-name', - dynamoDbClient, + dynamoDBClient, }); // 👇 Alternatively, provide a getter -const pokemonsEventsStorageAdapter = new DynamoDbEventStorageAdapter({ +const pokemonsEventStorageAdapter = new DynamoDBEventStorageAdapter({ tableName: () => process.env.MY_TABLE_NAME, - dynamoDbClient, + dynamoDBClient, }); const pokemonsEventStore = new EventStore({ ... - storageAdapter: pokemonsEventsStorageAdapter + eventStorageAdapter: pokemonsEventStorageAdapter }) ``` @@ -459,7 +459,7 @@ resource "aws_dynamodb_table" "pokemons-events-table" { ### 🤝 EventGroups -This adapter implements the [EventGroups](https://github.com/castore-dev/castore/#event-groups) API using the [DynamoDb Transactions API](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html): +This adapter implements the [EventGroups](https://github.com/castore-dev/castore/#event-groups) API using the [DynamoDB Transactions API](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html): ```ts import { EventStore } from '@castore/core'; @@ -476,7 +476,7 @@ await EventStore.pushEventGroup( Note that: -- All the event stores involved in the transaction need to use the `DynamoDbEventStorageAdapter` +- All the event stores involved in the transaction need to use the `DynamoDBEventStorageAdapter` - This util inherits of the [`TransactWriteItem` API](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txwriteitems) limitations: It can target up to 100 distinct events in one or more DynamoDB tables within the same AWS account and in the same Region. ### 🔑 IAM diff --git a/packages/dynamodb-event-storage-adapter/src/index.ts b/packages/dynamodb-event-storage-adapter/src/index.ts index 0d68906a..66278a18 100644 --- a/packages/dynamodb-event-storage-adapter/src/index.ts +++ b/packages/dynamodb-event-storage-adapter/src/index.ts @@ -1,5 +1,5 @@ -export { DynamoDbEventStorageAdapter } from './adapter'; -export { DynamoDbSingleTableEventStorageAdapter } from './singleTableAdapter'; +export { LegacyDynamoDBEventStorageAdapter } from './legacyAdapter'; +export { DynamoDBSingleTableEventStorageAdapter } from './singleTableAdapter'; export { EVENT_TABLE_PK, EVENT_TABLE_SK, @@ -11,6 +11,4 @@ export { EVENT_TABLE_EVENT_STORE_ID_KEY, EVENT_TABLE_INITIAL_EVENT_INDEX_NAME, } from './constants'; -export { formatEventForTransaction } from './utils/formatEventForTransaction'; -export { pushEventsTransaction } from './utils/pushEventsTransaction'; export { ImageParser } from './utils/imageParser'; diff --git a/packages/dynamodb-event-storage-adapter/src/adapter.ts b/packages/dynamodb-event-storage-adapter/src/legacyAdapter.ts similarity index 89% rename from packages/dynamodb-event-storage-adapter/src/adapter.ts rename to packages/dynamodb-event-storage-adapter/src/legacyAdapter.ts index 5f2b164d..a629f434 100644 --- a/packages/dynamodb-event-storage-adapter/src/adapter.ts +++ b/packages/dynamodb-event-storage-adapter/src/legacyAdapter.ts @@ -14,7 +14,7 @@ import type { Aggregate, EventDetail, PushEventOptions, - StorageAdapter, + EventStorageAdapter, } from '@castore/core'; import { GroupedEvent } from '@castore/core'; @@ -34,17 +34,17 @@ import { ParsedPageToken, } from './utils/parseAppliedListAggregateIdsOptions'; -type DynamoDbGroupedEvent< +type LegacyDynamoDBGroupedEvent< EVENT_DETAILS extends EventDetail = EventDetail, AGGREGATE extends Aggregate = Aggregate, > = GroupedEvent & { - eventStorageAdapter: DynamoDbEventStorageAdapter; + eventStorageAdapter: LegacyDynamoDBEventStorageAdapter; }; -const hasDynamoDbEventStorageAdapter = ( +const hasLegacyDynamoDBEventStorageAdapter = ( groupedEvent: GroupedEvent, -): groupedEvent is DynamoDbGroupedEvent => - groupedEvent.eventStorageAdapter instanceof DynamoDbEventStorageAdapter; +): groupedEvent is LegacyDynamoDBGroupedEvent => + groupedEvent.eventStorageAdapter instanceof LegacyDynamoDBEventStorageAdapter; const hasContext = ( groupedEvent: GroupedEvent, @@ -52,7 +52,7 @@ const hasContext = ( context: NonNullable; } => groupedEvent.context !== undefined; -type ParsedGroupedEvent = DynamoDbGroupedEvent & { +type ParsedGroupedEvent = LegacyDynamoDBGroupedEvent & { context: NonNullable; }; @@ -68,9 +68,9 @@ const parseGroupedEvents = ( const groupedEvents: ParsedGroupedEvent[] = []; groupedEventsInput.forEach((groupedEvent, groupedEventIndex) => { - if (!hasDynamoDbEventStorageAdapter(groupedEvent)) { + if (!hasLegacyDynamoDBEventStorageAdapter(groupedEvent)) { throw new Error( - `Event group event #${groupedEventIndex} is not connected to a DynamoDbEventStorageAdapter`, + `Event group event #${groupedEventIndex} is not connected to a DynamoDBEventStorageAdapter`, ); } @@ -119,36 +119,36 @@ const parseGroupedEvents = ( }; /** - * @deprecated "use DynamoDbSingleTableEventStorageAdapter instead: https://github.com/castore-dev/castore/blob/main/packages/dynamodb-event-storage-adapter/README.md#table-of-content" + * @deprecated "use DynamoDBSingleTableEventStorageAdapter instead: https://github.com/castore-dev/castore/blob/main/packages/dynamodb-event-storage-adapter/README.md#table-of-content" */ -export class DynamoDbEventStorageAdapter implements StorageAdapter { - getEvents: StorageAdapter['getEvents']; +export class LegacyDynamoDBEventStorageAdapter implements EventStorageAdapter { + getEvents: EventStorageAdapter['getEvents']; getPushEventInput: ( eventDetail: EventDetail, options: PushEventOptions, ) => PutItemCommandInput; - pushEvent: StorageAdapter['pushEvent']; - pushEventGroup: StorageAdapter['pushEventGroup']; - groupEvent: StorageAdapter['groupEvent']; - listAggregateIds: StorageAdapter['listAggregateIds']; + pushEvent: EventStorageAdapter['pushEvent']; + pushEventGroup: EventStorageAdapter['pushEventGroup']; + groupEvent: EventStorageAdapter['groupEvent']; + listAggregateIds: EventStorageAdapter['listAggregateIds']; - putSnapshot: StorageAdapter['putSnapshot']; - getLastSnapshot: StorageAdapter['getLastSnapshot']; - listSnapshots: StorageAdapter['listSnapshots']; + putSnapshot: EventStorageAdapter['putSnapshot']; + getLastSnapshot: EventStorageAdapter['getLastSnapshot']; + listSnapshots: EventStorageAdapter['listSnapshots']; getTableName: () => string; tableName: string | (() => string); - dynamoDbClient: DynamoDBClient; + dynamoDBClient: DynamoDBClient; constructor({ tableName, - dynamoDbClient, + dynamoDBClient, }: { tableName: string | (() => string); - dynamoDbClient: DynamoDBClient; + dynamoDBClient: DynamoDBClient; }) { this.tableName = tableName; - this.dynamoDbClient = dynamoDbClient; + this.dynamoDBClient = dynamoDBClient; this.getTableName = () => typeof this.tableName === 'string' ? this.tableName : this.tableName(); @@ -190,7 +190,7 @@ export class DynamoDbEventStorageAdapter implements StorageAdapter { ...(limit !== undefined ? { Limit: limit } : {}), }); - let eventsQueryResult = await this.dynamoDbClient.send( + let eventsQueryResult = await this.dynamoDBClient.send( eventsQueryCommand, ); marshalledEvents.push(...(eventsQueryResult.Items ?? [])); @@ -198,7 +198,7 @@ export class DynamoDbEventStorageAdapter implements StorageAdapter { while (eventsQueryResult.LastEvaluatedKey !== undefined) { eventsQueryCommand.input.ExclusiveStartKey = eventsQueryResult.LastEvaluatedKey; - eventsQueryResult = await this.dynamoDbClient.send(eventsQueryCommand); + eventsQueryResult = await this.dynamoDBClient.send(eventsQueryCommand); marshalledEvents.push(...(eventsQueryResult.Items ?? [])); } @@ -268,7 +268,7 @@ export class DynamoDbEventStorageAdapter implements StorageAdapter { const { aggregateId, version } = event; try { - await this.dynamoDbClient.send(putEventCommand); + await this.dynamoDBClient.send(putEventCommand); } catch (error) { if ( error instanceof Error && @@ -298,7 +298,7 @@ export class DynamoDbEventStorageAdapter implements StorageAdapter { const [firstGroupedEvent] = groupedEvents; const dynamodbClient = - firstGroupedEvent.eventStorageAdapter.dynamoDbClient; + firstGroupedEvent.eventStorageAdapter.dynamoDBClient; try { await dynamodbClient.send( @@ -405,7 +405,7 @@ export class DynamoDbEventStorageAdapter implements StorageAdapter { const { Items: unmarshalledInitialEvents = [], LastEvaluatedKey: lastEvaluatedKey, - } = await this.dynamoDbClient.send( + } = await this.dynamoDBClient.send( new QueryCommand(aggregateIdsQueryCommandInput), ); diff --git a/packages/dynamodb-event-storage-adapter/src/adapter.unit.test.ts b/packages/dynamodb-event-storage-adapter/src/legacyAdapter.unit.test.ts similarity index 84% rename from packages/dynamodb-event-storage-adapter/src/adapter.unit.test.ts rename to packages/dynamodb-event-storage-adapter/src/legacyAdapter.unit.test.ts index 5367c147..2f1d2e34 100644 --- a/packages/dynamodb-event-storage-adapter/src/adapter.unit.test.ts +++ b/packages/dynamodb-event-storage-adapter/src/legacyAdapter.unit.test.ts @@ -10,7 +10,6 @@ import { mockClient } from 'aws-sdk-client-mock'; import omit from 'lodash.omit'; import MockDate from 'mockdate'; -import { DynamoDbEventStorageAdapter } from './adapter'; import { EVENT_TABLE_PK, EVENT_TABLE_SK, @@ -19,14 +18,15 @@ import { EVENT_TABLE_TIMESTAMP_KEY, MARSHALL_OPTIONS, } from './constants'; +import { LegacyDynamoDBEventStorageAdapter } from './legacyAdapter'; -const dynamoDbClientMock = mockClient(DynamoDBClient); +const dynamoDBClientMock = mockClient(DynamoDBClient); const timestampA = '2022-01-01T00:00:00.000Z'; const timestampB = '2023-01-01T00:00:00.000Z'; const timestampC = '2024-01-01T00:00:00.000Z'; -const dynamoDbTableName = 'my-table-name'; +const dynamoDBTableName = 'my-table-name'; const eventStoreId = 'my-event-store'; const aggregateId = 'my-aggregate-id'; @@ -44,40 +44,40 @@ const secondEvent = { timestamp: timestampB, }; -describe('DynamoDbEventStorageAdapter', () => { +describe('LegacyDynamoDBEventStorageAdapter', () => { beforeEach(() => { - dynamoDbClientMock.reset(); - dynamoDbClientMock.on(PutItemCommand).resolves({}); - dynamoDbClientMock.on(QueryCommand).resolves({}); + dynamoDBClientMock.reset(); + dynamoDBClientMock.on(PutItemCommand).resolves({}); + dynamoDBClientMock.on(QueryCommand).resolves({}); }); - const adapter = new DynamoDbEventStorageAdapter({ - tableName: dynamoDbTableName, - dynamoDbClient: dynamoDbClientMock as unknown as DynamoDBClient, + const adapter = new LegacyDynamoDBEventStorageAdapter({ + tableName: dynamoDBTableName, + dynamoDBClient: dynamoDBClientMock as unknown as DynamoDBClient, }); describe('push event', () => { - it('sends a correct PutItemCommand to dynamoDbClient to push new event', async () => { + it('sends a correct PutItemCommand to dynamoDBClient to push new event', async () => { await adapter.pushEvent(secondEvent, { eventStoreId }); // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.calls()).toHaveLength(1); - expect(dynamoDbClientMock.call(0).args[0].input).toStrictEqual({ + expect(dynamoDBClientMock.calls()).toHaveLength(1); + expect(dynamoDBClientMock.call(0).args[0].input).toStrictEqual({ ConditionExpression: 'attribute_not_exists(#version)', ExpressionAttributeNames: { '#version': EVENT_TABLE_SK }, Item: marshall(secondEvent, MARSHALL_OPTIONS), - TableName: dynamoDbTableName, + TableName: dynamoDBTableName, }); }); - it('sends a correct PutItemCommand to dynamoDbClient to push new initial event', async () => { + it('sends a correct PutItemCommand to dynamoDBClient to push new initial event', async () => { await adapter.pushEvent(initialEvent, { eventStoreId }); // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.calls()).toHaveLength(1); - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.calls()).toHaveLength(1); + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ Item: marshall( { ...initialEvent, [EVENT_TABLE_IS_INITIAL_EVENT_KEY]: 1 }, MARSHALL_OPTIONS, @@ -92,7 +92,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ Item: marshall({ timestamp: timestampA }, MARSHALL_OPTIONS), }); @@ -104,8 +104,8 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.calls()).toHaveLength(1); - const input = dynamoDbClientMock.call(0).args[0].input; + expect(dynamoDBClientMock.calls()).toHaveLength(1); + const input = dynamoDBClientMock.call(0).args[0].input; expect(input).not.toHaveProperty('ConditionExpression'); expect(input).not.toHaveProperty('ExpressionAttributeNames'); }); @@ -113,21 +113,21 @@ describe('DynamoDbEventStorageAdapter', () => { describe('table name getter', () => { it('works with event bus name getters', async () => { - const adapterWithGetter = new DynamoDbEventStorageAdapter({ - tableName: () => dynamoDbTableName, - dynamoDbClient: dynamoDbClientMock as unknown as DynamoDBClient, + const adapterWithGetter = new LegacyDynamoDBEventStorageAdapter({ + tableName: () => dynamoDBTableName, + dynamoDBClient: dynamoDBClientMock as unknown as DynamoDBClient, }); await adapterWithGetter.pushEvent(initialEvent, { eventStoreId }); // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.calls()).toHaveLength(1); + expect(dynamoDBClientMock.calls()).toHaveLength(1); }); }); describe('get events', () => { - it('sends a correct QueryCommand to dynamoDbClient to get aggregate events', async () => { + it('sends a correct QueryCommand to dynamoDBClient to get aggregate events', async () => { const queryCommandOutputMock: QueryCommandOutput = { Items: [ marshall(initialEvent, MARSHALL_OPTIONS), @@ -136,14 +136,14 @@ describe('DynamoDbEventStorageAdapter', () => { $metadata: {}, }; - dynamoDbClientMock.on(QueryCommand).resolves(queryCommandOutputMock); + dynamoDBClientMock.on(QueryCommand).resolves(queryCommandOutputMock); const { events } = await adapter.getEvents(aggregateId, { eventStoreId }); // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.calls()).toHaveLength(1); - expect(dynamoDbClientMock.call(0).args[0].input).toStrictEqual({ + expect(dynamoDBClientMock.calls()).toHaveLength(1); + expect(dynamoDBClientMock.call(0).args[0].input).toStrictEqual({ ConsistentRead: true, ExpressionAttributeNames: { '#aggregateId': EVENT_TABLE_PK }, ExpressionAttributeValues: marshall( @@ -151,7 +151,7 @@ describe('DynamoDbEventStorageAdapter', () => { MARSHALL_OPTIONS, ), KeyConditionExpression: '#aggregateId = :aggregateId', - TableName: dynamoDbTableName, + TableName: dynamoDBTableName, }); // We have to serialize / deserialize because DynamoDB numbers are not regular numbers @@ -174,7 +174,7 @@ describe('DynamoDbEventStorageAdapter', () => { $metadata: {}, }; - dynamoDbClientMock + dynamoDBClientMock .on(QueryCommand) .resolvesOnce(firstQueryCommandOutputMock) .resolvesOnce(secondQueryCommandOutputMock); @@ -183,8 +183,8 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.calls()).toHaveLength(2); - expect(dynamoDbClientMock.call(1).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.calls()).toHaveLength(2); + expect(dynamoDBClientMock.call(1).args[0].input).toMatchObject({ ExclusiveStartKey: lastEvaluatedKey, }); @@ -200,7 +200,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ScanIndexForward: false, }); }); @@ -210,7 +210,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ExpressionAttributeNames: { '#aggregateId': EVENT_TABLE_PK, '#version': EVENT_TABLE_SK, @@ -232,7 +232,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ExpressionAttributeNames: { '#aggregateId': EVENT_TABLE_PK, '#version': EVENT_TABLE_SK, @@ -258,7 +258,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ExpressionAttributeNames: { '#aggregateId': EVENT_TABLE_PK, '#version': EVENT_TABLE_SK, @@ -281,7 +281,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ Limit: 2, }); }); @@ -298,7 +298,7 @@ describe('DynamoDbEventStorageAdapter', () => { MARSHALL_OPTIONS, ); - it('sends a correct QueryCommand to dynamoDbClient to list aggregate ids', async () => { + it('sends a correct QueryCommand to dynamoDBClient to list aggregate ids', async () => { const secondAggregateIdMock = 'my-second-aggregate-id'; const queryCommandOutputMock: QueryCommandOutput = { Items: [ @@ -308,21 +308,21 @@ describe('DynamoDbEventStorageAdapter', () => { $metadata: {}, }; - dynamoDbClientMock.on(QueryCommand).resolves(queryCommandOutputMock); + dynamoDBClientMock.on(QueryCommand).resolves(queryCommandOutputMock); const { aggregateIds } = await adapter.listAggregateIds({ eventStoreId }); // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.calls()).toHaveLength(1); - expect(dynamoDbClientMock.call(0).args[0].input).toStrictEqual({ + expect(dynamoDBClientMock.calls()).toHaveLength(1); + expect(dynamoDBClientMock.call(0).args[0].input).toStrictEqual({ ExpressionAttributeNames: { '#isInitialEvent': EVENT_TABLE_IS_INITIAL_EVENT_KEY, }, ExpressionAttributeValues: marshall({ ':true': 1 }, MARSHALL_OPTIONS), IndexName: EVENT_TABLE_INITIAL_EVENT_INDEX_NAME, KeyConditionExpression: '#isInitialEvent = :true', - TableName: dynamoDbTableName, + TableName: dynamoDBTableName, }); // We have to serialize / deserialize because DynamoDB numbers are not regular numbers @@ -334,7 +334,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ Limit: 1, }); }); @@ -347,7 +347,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ExpressionAttributeNames: { '#timestamp': EVENT_TABLE_TIMESTAMP_KEY, }, @@ -369,7 +369,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ExpressionAttributeNames: { '#timestamp': EVENT_TABLE_TIMESTAMP_KEY, }, @@ -391,7 +391,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ExpressionAttributeNames: { '#timestamp': EVENT_TABLE_TIMESTAMP_KEY, }, @@ -413,7 +413,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ScanIndexForward: false, }); }); @@ -425,7 +425,7 @@ describe('DynamoDbEventStorageAdapter', () => { $metadata: {}, }; - dynamoDbClientMock.on(QueryCommand).resolves(queryCommandOutputMock); + dynamoDBClientMock.on(QueryCommand).resolves(queryCommandOutputMock); const { nextPageToken } = await adapter.listAggregateIds( { eventStoreId }, @@ -462,7 +462,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ Limit: 1, ScanIndexForward: false, ExclusiveStartKey: lastEvaluatedKey, @@ -501,7 +501,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ Limit: 2, ScanIndexForward: true, ExclusiveStartKey: lastEvaluatedKey, diff --git a/packages/dynamodb-event-storage-adapter/src/singleTableAdapter.ts b/packages/dynamodb-event-storage-adapter/src/singleTableAdapter.ts index 750309ee..035fa201 100644 --- a/packages/dynamodb-event-storage-adapter/src/singleTableAdapter.ts +++ b/packages/dynamodb-event-storage-adapter/src/singleTableAdapter.ts @@ -13,7 +13,7 @@ import { marshall, unmarshall } from '@aws-sdk/util-dynamodb'; import type { Aggregate, EventDetail, - StorageAdapter, + EventStorageAdapter, PushEventOptions, } from '@castore/core'; import { GroupedEvent } from '@castore/core'; @@ -45,18 +45,18 @@ const unprefixAggregateId = ( ? aggregateId.slice(eventStoreId.length + 1) : aggregateId; -type DynamoDbSingleTableGroupedEvent< +type DynamoDBSingleTableGroupedEvent< EVENT_DETAILS extends EventDetail = EventDetail, AGGREGATE extends Aggregate = Aggregate, > = GroupedEvent & { - eventStorageAdapter: DynamoDbSingleTableEventStorageAdapter; + eventStorageAdapter: DynamoDBSingleTableEventStorageAdapter; }; -const hasDynamoDbSingleTableEventStorageAdapter = ( +const hasDynamoDBSingleTableEventStorageAdapter = ( groupedEvent: GroupedEvent, -): groupedEvent is DynamoDbSingleTableGroupedEvent => +): groupedEvent is DynamoDBSingleTableGroupedEvent => groupedEvent.eventStorageAdapter instanceof - DynamoDbSingleTableEventStorageAdapter; + DynamoDBSingleTableEventStorageAdapter; const hasContext = ( groupedEvent: GroupedEvent, @@ -64,7 +64,7 @@ const hasContext = ( context: NonNullable; } => groupedEvent.context !== undefined; -type ParsedGroupedEvent = DynamoDbSingleTableGroupedEvent & { +type ParsedGroupedEvent = DynamoDBSingleTableGroupedEvent & { context: NonNullable; }; @@ -80,9 +80,9 @@ const parseGroupedEvents = ( const groupedEvents: ParsedGroupedEvent[] = []; groupedEventsInput.forEach((groupedEvent, groupedEventIndex) => { - if (!hasDynamoDbSingleTableEventStorageAdapter(groupedEvent)) { + if (!hasDynamoDBSingleTableEventStorageAdapter(groupedEvent)) { throw new Error( - `Event group event #${groupedEventIndex} is not connected to a DynamoDbEventStorageAdapter`, + `Event group event #${groupedEventIndex} is not connected to a DynamoDBEventStorageAdapter`, ); } @@ -130,34 +130,36 @@ const parseGroupedEvents = ( }; }; -export class DynamoDbSingleTableEventStorageAdapter implements StorageAdapter { - getEvents: StorageAdapter['getEvents']; +export class DynamoDBSingleTableEventStorageAdapter + implements EventStorageAdapter +{ + getEvents: EventStorageAdapter['getEvents']; getPushEventInput: ( eventDetail: EventDetail, options: PushEventOptions, ) => PutItemCommandInput; - pushEvent: StorageAdapter['pushEvent']; - pushEventGroup: StorageAdapter['pushEventGroup']; - groupEvent: StorageAdapter['groupEvent']; - listAggregateIds: StorageAdapter['listAggregateIds']; + pushEvent: EventStorageAdapter['pushEvent']; + pushEventGroup: EventStorageAdapter['pushEventGroup']; + groupEvent: EventStorageAdapter['groupEvent']; + listAggregateIds: EventStorageAdapter['listAggregateIds']; - putSnapshot: StorageAdapter['putSnapshot']; - getLastSnapshot: StorageAdapter['getLastSnapshot']; - listSnapshots: StorageAdapter['listSnapshots']; + putSnapshot: EventStorageAdapter['putSnapshot']; + getLastSnapshot: EventStorageAdapter['getLastSnapshot']; + listSnapshots: EventStorageAdapter['listSnapshots']; getTableName: () => string; tableName: string | (() => string); - dynamoDbClient: DynamoDBClient; + dynamoDBClient: DynamoDBClient; constructor({ tableName, - dynamoDbClient, + dynamoDBClient, }: { tableName: string | (() => string); - dynamoDbClient: DynamoDBClient; + dynamoDBClient: DynamoDBClient; }) { this.tableName = tableName; - this.dynamoDbClient = dynamoDbClient; + this.dynamoDBClient = dynamoDBClient; this.getTableName = () => typeof this.tableName === 'string' ? this.tableName : this.tableName(); @@ -199,7 +201,7 @@ export class DynamoDbSingleTableEventStorageAdapter implements StorageAdapter { ...(limit !== undefined ? { Limit: limit } : {}), }); - let eventsQueryResult = await this.dynamoDbClient.send( + let eventsQueryResult = await this.dynamoDBClient.send( eventsQueryCommand, ); marshalledEvents.push(...(eventsQueryResult.Items ?? [])); @@ -207,7 +209,7 @@ export class DynamoDbSingleTableEventStorageAdapter implements StorageAdapter { while (eventsQueryResult.LastEvaluatedKey !== undefined) { eventsQueryCommand.input.ExclusiveStartKey = eventsQueryResult.LastEvaluatedKey; - eventsQueryResult = await this.dynamoDbClient.send(eventsQueryCommand); + eventsQueryResult = await this.dynamoDBClient.send(eventsQueryCommand); marshalledEvents.push(...(eventsQueryResult.Items ?? [])); } @@ -278,7 +280,7 @@ export class DynamoDbSingleTableEventStorageAdapter implements StorageAdapter { const { aggregateId, version } = event; try { - await this.dynamoDbClient.send(putEventCommand); + await this.dynamoDBClient.send(putEventCommand); } catch (error) { if ( error instanceof Error && @@ -308,7 +310,7 @@ export class DynamoDbSingleTableEventStorageAdapter implements StorageAdapter { const [firstGroupedEvent] = groupedEvents; const dynamodbClient = - firstGroupedEvent.eventStorageAdapter.dynamoDbClient; + firstGroupedEvent.eventStorageAdapter.dynamoDBClient; try { await dynamodbClient.send( @@ -418,7 +420,7 @@ export class DynamoDbSingleTableEventStorageAdapter implements StorageAdapter { const { Items: unmarshalledInitialEvents = [], LastEvaluatedKey: lastEvaluatedKey, - } = await this.dynamoDbClient.send( + } = await this.dynamoDBClient.send( new QueryCommand(aggregateIdsQueryCommandInput), ); diff --git a/packages/dynamodb-event-storage-adapter/src/singleTableAdapter.unit.test.ts b/packages/dynamodb-event-storage-adapter/src/singleTableAdapter.unit.test.ts index 42601f7e..5213d273 100644 --- a/packages/dynamodb-event-storage-adapter/src/singleTableAdapter.unit.test.ts +++ b/packages/dynamodb-event-storage-adapter/src/singleTableAdapter.unit.test.ts @@ -18,15 +18,15 @@ import { EVENT_TABLE_EVENT_STORE_ID_KEY, MARSHALL_OPTIONS, } from './constants'; -import { DynamoDbSingleTableEventStorageAdapter } from './singleTableAdapter'; +import { DynamoDBSingleTableEventStorageAdapter } from './singleTableAdapter'; -const dynamoDbClientMock = mockClient(DynamoDBClient); +const dynamoDBClientMock = mockClient(DynamoDBClient); const timestampA = '2022-01-01T00:00:00.000Z'; const timestampB = '2023-01-01T00:00:00.000Z'; const timestampC = '2024-01-01T00:00:00.000Z'; -const dynamoDbTableName = 'my-table-name'; +const dynamoDBTableName = 'my-table-name'; const eventStoreId = 'my-event-store'; const aggregateId = 'my-aggregate-id'; @@ -58,40 +58,40 @@ const savedSecondEvent = { aggregateId: prefixedAggregateId, }; -describe('DynamoDbEventStorageAdapter', () => { +describe('DynamoDBEventStorageAdapter', () => { beforeEach(() => { - dynamoDbClientMock.reset(); - dynamoDbClientMock.on(PutItemCommand).resolves({}); - dynamoDbClientMock.on(QueryCommand).resolves({}); + dynamoDBClientMock.reset(); + dynamoDBClientMock.on(PutItemCommand).resolves({}); + dynamoDBClientMock.on(QueryCommand).resolves({}); }); - const adapter = new DynamoDbSingleTableEventStorageAdapter({ - tableName: dynamoDbTableName, - dynamoDbClient: dynamoDbClientMock as unknown as DynamoDBClient, + const adapter = new DynamoDBSingleTableEventStorageAdapter({ + tableName: dynamoDBTableName, + dynamoDBClient: dynamoDBClientMock as unknown as DynamoDBClient, }); describe('push event', () => { - it('sends a correct PutItemCommand to dynamoDbClient to push new event', async () => { + it('sends a correct PutItemCommand to dynamoDBClient to push new event', async () => { await adapter.pushEvent(secondEvent, { eventStoreId }); // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.calls()).toHaveLength(1); - expect(dynamoDbClientMock.call(0).args[0].input).toStrictEqual({ + expect(dynamoDBClientMock.calls()).toHaveLength(1); + expect(dynamoDBClientMock.call(0).args[0].input).toStrictEqual({ ConditionExpression: 'attribute_not_exists(#version)', ExpressionAttributeNames: { '#version': EVENT_TABLE_SK }, Item: marshall(savedSecondEvent, MARSHALL_OPTIONS), - TableName: dynamoDbTableName, + TableName: dynamoDBTableName, }); }); - it('sends a correct PutItemCommand to dynamoDbClient to push new initial event', async () => { + it('sends a correct PutItemCommand to dynamoDBClient to push new initial event', async () => { await adapter.pushEvent(initialEvent, { eventStoreId }); // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.calls()).toHaveLength(1); - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.calls()).toHaveLength(1); + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ Item: marshall(savedInitialEvent, MARSHALL_OPTIONS), }); }); @@ -103,7 +103,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ Item: marshall({ timestamp: timestampA }, MARSHALL_OPTIONS), }); @@ -115,8 +115,8 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.calls()).toHaveLength(1); - const input = dynamoDbClientMock.call(0).args[0].input; + expect(dynamoDBClientMock.calls()).toHaveLength(1); + const input = dynamoDBClientMock.call(0).args[0].input; expect(input).not.toHaveProperty('ConditionExpression'); expect(input).not.toHaveProperty('ExpressionAttributeNames'); }); @@ -124,21 +124,21 @@ describe('DynamoDbEventStorageAdapter', () => { describe('table name getter', () => { it('works with event bus name getters', async () => { - const adapterWithGetter = new DynamoDbSingleTableEventStorageAdapter({ - tableName: () => dynamoDbTableName, - dynamoDbClient: dynamoDbClientMock as unknown as DynamoDBClient, + const adapterWithGetter = new DynamoDBSingleTableEventStorageAdapter({ + tableName: () => dynamoDBTableName, + dynamoDBClient: dynamoDBClientMock as unknown as DynamoDBClient, }); await adapterWithGetter.pushEvent(initialEvent, { eventStoreId }); // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.calls()).toHaveLength(1); + expect(dynamoDBClientMock.calls()).toHaveLength(1); }); }); describe('get events', () => { - it('sends a correct QueryCommand to dynamoDbClient to get aggregate events', async () => { + it('sends a correct QueryCommand to dynamoDBClient to get aggregate events', async () => { const queryCommandOutputMock: QueryCommandOutput = { Items: [ marshall(savedInitialEvent, MARSHALL_OPTIONS), @@ -147,14 +147,14 @@ describe('DynamoDbEventStorageAdapter', () => { $metadata: {}, }; - dynamoDbClientMock.on(QueryCommand).resolves(queryCommandOutputMock); + dynamoDBClientMock.on(QueryCommand).resolves(queryCommandOutputMock); const { events } = await adapter.getEvents(aggregateId, { eventStoreId }); // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.calls()).toHaveLength(1); - expect(dynamoDbClientMock.call(0).args[0].input).toStrictEqual({ + expect(dynamoDBClientMock.calls()).toHaveLength(1); + expect(dynamoDBClientMock.call(0).args[0].input).toStrictEqual({ ConsistentRead: true, ExpressionAttributeNames: { '#aggregateId': EVENT_TABLE_PK }, ExpressionAttributeValues: marshall( @@ -162,7 +162,7 @@ describe('DynamoDbEventStorageAdapter', () => { MARSHALL_OPTIONS, ), KeyConditionExpression: '#aggregateId = :aggregateId', - TableName: dynamoDbTableName, + TableName: dynamoDBTableName, }); // We have to serialize / deserialize because DynamoDB numbers are not regular numbers @@ -185,7 +185,7 @@ describe('DynamoDbEventStorageAdapter', () => { $metadata: {}, }; - dynamoDbClientMock + dynamoDBClientMock .on(QueryCommand) .resolvesOnce(firstQueryCommandOutputMock) .resolvesOnce(secondQueryCommandOutputMock); @@ -194,8 +194,8 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.calls()).toHaveLength(2); - expect(dynamoDbClientMock.call(1).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.calls()).toHaveLength(2); + expect(dynamoDBClientMock.call(1).args[0].input).toMatchObject({ ExclusiveStartKey: lastEvaluatedKey, }); @@ -211,7 +211,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ScanIndexForward: false, }); }); @@ -221,7 +221,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ExpressionAttributeNames: { '#version': EVENT_TABLE_SK }, ExpressionAttributeValues: marshall( { ':minVersion': 3 }, @@ -237,7 +237,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ExpressionAttributeNames: { '#version': EVENT_TABLE_SK }, ExpressionAttributeValues: marshall( { ':maxVersion': 5 }, @@ -257,7 +257,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ExpressionAttributeNames: { '#version': EVENT_TABLE_SK }, ExpressionAttributeValues: marshall( { ':minVersion': 3, ':maxVersion': 5 }, @@ -273,7 +273,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ Limit: 2, }); }); @@ -290,7 +290,7 @@ describe('DynamoDbEventStorageAdapter', () => { MARSHALL_OPTIONS, ); - it('sends a correct QueryCommand to dynamoDbClient to list aggregate ids', async () => { + it('sends a correct QueryCommand to dynamoDBClient to list aggregate ids', async () => { const secondAggregateIdMock = 'my-second-aggregate-id'; const queryCommandOutputMock: QueryCommandOutput = { Items: [ @@ -302,14 +302,14 @@ describe('DynamoDbEventStorageAdapter', () => { $metadata: {}, }; - dynamoDbClientMock.on(QueryCommand).resolves(queryCommandOutputMock); + dynamoDBClientMock.on(QueryCommand).resolves(queryCommandOutputMock); const { aggregateIds } = await adapter.listAggregateIds({ eventStoreId }); // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.calls()).toHaveLength(1); - expect(dynamoDbClientMock.call(0).args[0].input).toStrictEqual({ + expect(dynamoDBClientMock.calls()).toHaveLength(1); + expect(dynamoDBClientMock.call(0).args[0].input).toStrictEqual({ ExpressionAttributeNames: { '#eventStoreId': EVENT_TABLE_EVENT_STORE_ID_KEY, }, @@ -319,7 +319,7 @@ describe('DynamoDbEventStorageAdapter', () => { ), IndexName: EVENT_TABLE_INITIAL_EVENT_INDEX_NAME, KeyConditionExpression: '#eventStoreId = :eventStoreId', - TableName: dynamoDbTableName, + TableName: dynamoDBTableName, }); // We have to serialize / deserialize because DynamoDB numbers are not regular numbers @@ -331,7 +331,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ Limit: 1, }); }); @@ -344,7 +344,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ExpressionAttributeNames: { '#timestamp': EVENT_TABLE_TIMESTAMP_KEY, }, @@ -366,7 +366,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ExpressionAttributeNames: { '#timestamp': EVENT_TABLE_TIMESTAMP_KEY, }, @@ -388,7 +388,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ExpressionAttributeNames: { '#timestamp': EVENT_TABLE_TIMESTAMP_KEY, }, @@ -410,7 +410,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ ScanIndexForward: false, }); }); @@ -424,7 +424,7 @@ describe('DynamoDbEventStorageAdapter', () => { $metadata: {}, }; - dynamoDbClientMock.on(QueryCommand).resolves(queryCommandOutputMock); + dynamoDBClientMock.on(QueryCommand).resolves(queryCommandOutputMock); const { nextPageToken } = await adapter.listAggregateIds( { eventStoreId }, @@ -461,7 +461,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ Limit: 1, ScanIndexForward: false, ExclusiveStartKey: lastEvaluatedKey, @@ -500,7 +500,7 @@ describe('DynamoDbEventStorageAdapter', () => { // regularly check if vitest matchers are available (toHaveReceivedCommandWith) // https://github.com/m-radzikowski/aws-sdk-client-mock/issues/139 - expect(dynamoDbClientMock.call(0).args[0].input).toMatchObject({ + expect(dynamoDBClientMock.call(0).args[0].input).toMatchObject({ Limit: 2, ScanIndexForward: true, ExclusiveStartKey: lastEvaluatedKey, diff --git a/packages/dynamodb-event-storage-adapter/src/utils/formatEventForTransaction.ts b/packages/dynamodb-event-storage-adapter/src/utils/formatEventForTransaction.ts deleted file mode 100644 index 1aa6e027..00000000 --- a/packages/dynamodb-event-storage-adapter/src/utils/formatEventForTransaction.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { - DynamoDBClient, - TransactWriteItem, -} from '@aws-sdk/client-dynamodb'; - -import type { EventStore, EventStoreEventsDetails } from '@castore/core'; - -import { DynamoDbEventStorageAdapter } from '../adapter'; - -export interface EventTransaction { - transactItem: TransactWriteItem; - dynamoDbClient: DynamoDBClient; -} - -/** - * @deprecated Use `eventStore.groupEvent` instead - */ -export const formatEventForTransaction = ( - eventStore: EVENT_STORE, - eventDetail: EventStoreEventsDetails, -): EventTransaction => { - const { eventStoreId, storageAdapter } = eventStore; - - if (!(storageAdapter instanceof DynamoDbEventStorageAdapter)) { - throw new Error( - `The event storage adapter of event store ${eventStoreId} is not an instance of DynamoDbEventStorageAdapter and cannot use pushEventTransaction`, - ); - } - - const { dynamoDbClient } = storageAdapter; - - return { - transactItem: { - Put: storageAdapter.getPushEventInput(eventDetail, { eventStoreId }), - }, - dynamoDbClient, - }; -}; diff --git a/packages/dynamodb-event-storage-adapter/src/utils/formatEventForTransaction.unit.test.ts b/packages/dynamodb-event-storage-adapter/src/utils/formatEventForTransaction.unit.test.ts deleted file mode 100644 index 8741130e..00000000 --- a/packages/dynamodb-event-storage-adapter/src/utils/formatEventForTransaction.unit.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; -import { mockClient } from 'aws-sdk-client-mock'; - -import { - pokemonsEventStore, - pikachuAppearedEvent, -} from '@castore/demo-blueprint'; - -import { DynamoDbEventStorageAdapter } from '../adapter'; -import { formatEventForTransaction } from './formatEventForTransaction'; - -describe('formatEventForTransaction', () => { - const dynamoDbClientMock = mockClient(DynamoDBClient); - - const storageAdapter = new DynamoDbEventStorageAdapter({ - tableName: 'tableNameMock', - dynamoDbClient: dynamoDbClientMock as unknown as DynamoDBClient, - }); - - pokemonsEventStore.storageAdapter = storageAdapter; - - it('returns expected grouped event', () => { - expect( - formatEventForTransaction(pokemonsEventStore, pikachuAppearedEvent), - ).toStrictEqual({ - dynamoDbClient: dynamoDbClientMock, - transactItem: { - Put: storageAdapter.getPushEventInput(pikachuAppearedEvent, { - eventStoreId: pokemonsEventStore.eventStoreId, - }), - }, - }); - }); - - it('throws if storage adapter is not an instance of DynamoDBEventStorageAdapter', () => { - pokemonsEventStore.storageAdapter = undefined; - - expect(() => - formatEventForTransaction(pokemonsEventStore, pikachuAppearedEvent), - ).toThrow( - `The event storage adapter of event store ${pokemonsEventStore.eventStoreId} is not an instance of DynamoDbEventStorageAdapter and cannot use pushEventTransaction`, - ); - }); -}); diff --git a/packages/dynamodb-event-storage-adapter/src/utils/pushEventsTransaction.ts b/packages/dynamodb-event-storage-adapter/src/utils/pushEventsTransaction.ts deleted file mode 100644 index 3a0b4765..00000000 --- a/packages/dynamodb-event-storage-adapter/src/utils/pushEventsTransaction.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { - DynamoDBClient, - TransactWriteItemsCommand, - TransactWriteItemsCommandOutput, -} from '@aws-sdk/client-dynamodb'; - -import type { EventTransaction } from './formatEventForTransaction'; - -/** - * @deprecated Use static method `EventStore.pushEventGroup` instead - */ -export const pushEventsTransaction = async ( - eventsTransaction: [EventTransaction, ...EventTransaction[]], - options: { dynamoDbClient?: DynamoDBClient } = {}, -): Promise => { - if (eventsTransaction.length === 0) { - throw new Error('No event to push'); - } - - const dynamodbClient = - options.dynamoDbClient ?? eventsTransaction[0].dynamoDbClient; - - /** - * @debt bug "TODO: ensure that pushEventsTransaction throws an EventAlreadyExists error if transaction fails" - */ - return dynamodbClient.send( - new TransactWriteItemsCommand({ - TransactItems: eventsTransaction.map(({ transactItem }) => transactItem), - }), - ); -}; diff --git a/packages/dynamodb-event-storage-adapter/src/utils/pushEventsTransaction.unit.test.ts b/packages/dynamodb-event-storage-adapter/src/utils/pushEventsTransaction.unit.test.ts deleted file mode 100644 index 94d3be60..00000000 --- a/packages/dynamodb-event-storage-adapter/src/utils/pushEventsTransaction.unit.test.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { - DynamoDBClient, - TransactWriteItemsCommand, -} from '@aws-sdk/client-dynamodb'; -import { mockClient } from 'aws-sdk-client-mock'; - -import { - ashPokemonCaughtEvent, - pikachuCaughtEvent, - pokemonsEventStore, - trainersEventStore, -} from '@castore/demo-blueprint'; - -import { DynamoDbEventStorageAdapter } from '../adapter'; -import { formatEventForTransaction } from './formatEventForTransaction'; -import { pushEventsTransaction } from './pushEventsTransaction'; - -describe('pushEventsTransaction', () => { - const dynamoDbClientMockSeemless = mockClient(DynamoDBClient); - const dynamoDbClientMockOption = mockClient(DynamoDBClient); - - const pokemonsStorageAdapter = new DynamoDbEventStorageAdapter({ - tableName: 'pokemonsTableNameMock', - dynamoDbClient: dynamoDbClientMockSeemless as unknown as DynamoDBClient, - }); - - const trainersStorageAdapter = new DynamoDbEventStorageAdapter({ - tableName: 'trainersTableNameMock', - dynamoDbClient: dynamoDbClientMockSeemless as unknown as DynamoDBClient, - }); - - pokemonsEventStore.storageAdapter = pokemonsStorageAdapter; - trainersEventStore.storageAdapter = trainersStorageAdapter; - - beforeEach(() => { - dynamoDbClientMockSeemless.reset(); - dynamoDbClientMockOption.reset(); - }); - - it('throws if no transaction has been inputted', async () => { - // @ts-expect-error pushEventsTransaction expects at least 1 item - await expect(pushEventsTransaction([])).rejects.toThrow('No event to push'); - }); - - it('sends correct command', async () => { - await pushEventsTransaction([ - formatEventForTransaction(pokemonsEventStore, pikachuCaughtEvent), - formatEventForTransaction(trainersEventStore, ashPokemonCaughtEvent), - ]); - - expect(dynamoDbClientMockSeemless.calls()).toHaveLength(1); - expect(dynamoDbClientMockSeemless.calls()[0]?.args[0]).toBeInstanceOf( - TransactWriteItemsCommand, - ); - expect(dynamoDbClientMockSeemless.calls()[0]?.args[0].input).toStrictEqual({ - TransactItems: [ - formatEventForTransaction(pokemonsEventStore, pikachuCaughtEvent) - .transactItem, - formatEventForTransaction(trainersEventStore, ashPokemonCaughtEvent) - .transactItem, - ], - }); - - expect(dynamoDbClientMockOption.calls()).toHaveLength(0); - }); - - it('uses options dynamoDbClient if one has been provided', async () => { - await pushEventsTransaction( - [ - formatEventForTransaction(pokemonsEventStore, pikachuCaughtEvent), - formatEventForTransaction(trainersEventStore, ashPokemonCaughtEvent), - ], - { dynamoDbClient: dynamoDbClientMockOption as unknown as DynamoDBClient }, - ); - - expect(dynamoDbClientMockSeemless.calls()).toHaveLength(0); - - expect(dynamoDbClientMockOption.calls()).toHaveLength(1); - expect(dynamoDbClientMockOption.calls()[0]?.args[0]).toBeInstanceOf( - TransactWriteItemsCommand, - ); - expect(dynamoDbClientMockOption.calls()[0]?.args[0].input).toStrictEqual({ - TransactItems: [ - formatEventForTransaction(pokemonsEventStore, pikachuCaughtEvent) - .transactItem, - formatEventForTransaction(trainersEventStore, ashPokemonCaughtEvent) - .transactItem, - ], - }); - }); -}); diff --git a/packages/inmemory-event-storage-adapter/README.md b/packages/inmemory-event-storage-adapter/README.md index b2456c18..caa73f14 100644 --- a/packages/inmemory-event-storage-adapter/README.md +++ b/packages/inmemory-event-storage-adapter/README.md @@ -27,9 +27,9 @@ yarn add @castore/core ## 👩‍💻 Usage ```ts -import { InMemoryStorageAdapter } from '@castore/inmemory-event-storage-adapter'; +import { InMemoryEventStorageAdapter } from '@castore/inmemory-event-storage-adapter'; -const pokemonsEventsStorageAdapter = new InMemoryStorageAdapter({ +const pokemonsEventStorageAdapter = new InMemoryEventStorageAdapter({ // 👇 You can specify an initial state for your event store initialEvents: [ { @@ -41,7 +41,7 @@ const pokemonsEventsStorageAdapter = new InMemoryStorageAdapter({ const pokemonsEventStore = new EventStore({ ... - storageAdapter: pokemonsEventsStorageAdapter, + eventStorageAdapter: pokemonsEventStorageAdapter, }); ``` diff --git a/packages/inmemory-event-storage-adapter/src/adapter.ts b/packages/inmemory-event-storage-adapter/src/adapter.ts index 9472d9cf..8b8a65dd 100644 --- a/packages/inmemory-event-storage-adapter/src/adapter.ts +++ b/packages/inmemory-event-storage-adapter/src/adapter.ts @@ -3,7 +3,7 @@ import type { Aggregate, EventDetail, PushEventOptions, - StorageAdapter, + EventStorageAdapter, } from '@castore/core'; import { GroupedEvent } from '@castore/core'; @@ -17,13 +17,13 @@ type InMemoryGroupedEvent< EVENT_DETAILS extends EventDetail = EventDetail, AGGREGATE extends Aggregate = Aggregate, > = GroupedEvent & { - eventStorageAdapter: InMemoryStorageAdapter; + eventStorageAdapter: InMemoryEventStorageAdapter; }; -const hasInMemoryStorageAdapter = ( +const hasInMemoryEventStorageAdapter = ( groupedEvent: GroupedEvent, ): groupedEvent is InMemoryGroupedEvent => - groupedEvent.eventStorageAdapter instanceof InMemoryStorageAdapter; + groupedEvent.eventStorageAdapter instanceof InMemoryEventStorageAdapter; const hasContext = ( groupedEvent: GroupedEvent, @@ -47,7 +47,7 @@ const parseGroupedEvents = ( })[] = []; groupedEventsInput.forEach((groupedEvent, groupedEventIndex) => { - if (!hasInMemoryStorageAdapter(groupedEvent)) { + if (!hasInMemoryEventStorageAdapter(groupedEvent)) { throw new Error( `Event group event #${groupedEventIndex} is not connected to a InMemoryEventStorageAdapter`, ); @@ -109,19 +109,19 @@ const getInitialEventTimestamp = ( return initialEventTimestamp; }; -export class InMemoryStorageAdapter implements StorageAdapter { - getEvents: StorageAdapter['getEvents']; +export class InMemoryEventStorageAdapter implements EventStorageAdapter { + getEvents: EventStorageAdapter['getEvents']; pushEventSync: ( eventDetail: EventDetail, options: PushEventOptions, - ) => Awaited>; - pushEvent: StorageAdapter['pushEvent']; - pushEventGroup: StorageAdapter['pushEventGroup']; - groupEvent: StorageAdapter['groupEvent']; - listAggregateIds: StorageAdapter['listAggregateIds']; - putSnapshot: StorageAdapter['putSnapshot']; - getLastSnapshot: StorageAdapter['getLastSnapshot']; - listSnapshots: StorageAdapter['listSnapshots']; + ) => Awaited>; + pushEvent: EventStorageAdapter['pushEvent']; + pushEventGroup: EventStorageAdapter['pushEventGroup']; + groupEvent: EventStorageAdapter['groupEvent']; + listAggregateIds: EventStorageAdapter['listAggregateIds']; + putSnapshot: EventStorageAdapter['putSnapshot']; + getLastSnapshot: EventStorageAdapter['getLastSnapshot']; + listSnapshots: EventStorageAdapter['listSnapshots']; eventStore: { [aggregateId: string]: EventDetail[] }; @@ -201,20 +201,22 @@ export class InMemoryStorageAdapter implements StorageAdapter { .reverse() .forEach(groupedEventToRevert => { const { - eventStorageAdapter: eventToRevertStorageAdapter, + eventStorageAdapter: eventToRevertEventStorageAdapter, event: eventToRevert, } = groupedEventToRevert; const { aggregateId, version } = eventToRevert; const revertedEvent = - eventToRevertStorageAdapter.eventStore[aggregateId]?.pop(); + eventToRevertEventStorageAdapter.eventStore[ + aggregateId + ]?.pop(); // Check that version is indeed last pushed event if (revertedEvent?.version !== version) { if (revertedEvent !== undefined) { - eventToRevertStorageAdapter.eventStore[aggregateId]?.push( - revertedEvent, - ); + eventToRevertEventStorageAdapter.eventStore[ + aggregateId + ]?.push(revertedEvent); } throw new Error( diff --git a/packages/inmemory-event-storage-adapter/src/adapter.unit.test.ts b/packages/inmemory-event-storage-adapter/src/adapter.unit.test.ts index 6ce1638c..8b9262c9 100644 --- a/packages/inmemory-event-storage-adapter/src/adapter.unit.test.ts +++ b/packages/inmemory-event-storage-adapter/src/adapter.unit.test.ts @@ -3,9 +3,9 @@ import { randomUUID } from 'crypto'; import omit from 'lodash.omit'; import MockDate from 'mockdate'; -import { GroupedEvent, StorageAdapter } from '@castore/core'; +import { GroupedEvent, EventStorageAdapter } from '@castore/core'; -import { InMemoryStorageAdapter } from './adapter'; +import { InMemoryEventStorageAdapter } from './adapter'; import { InMemoryEventAlreadyExistsError } from './error'; const eventStoreId = 'eventStoreId'; @@ -29,12 +29,12 @@ const eventMock2 = { describe('in-memory storage adapter', () => { describe('constructor', () => { - const storageAdapter = new InMemoryStorageAdapter({ + const eventStorageAdapter = new InMemoryEventStorageAdapter({ initialEvents: [eventMock1, eventMock2], }); it('fills the db with initial events', () => { - expect(storageAdapter.eventStore).toStrictEqual({ + expect(eventStorageAdapter.eventStore).toStrictEqual({ [aggregateIdMock1]: [eventMock1, eventMock2], }); }); @@ -42,25 +42,25 @@ describe('in-memory storage adapter', () => { describe('methods', () => { describe('getEvents / pushEvent', () => { - const storageAdapter = new InMemoryStorageAdapter(); + const eventStorageAdapter = new InMemoryEventStorageAdapter(); it('gets an empty array if there is no event for aggregateId', async () => { - const response = await storageAdapter.getEvents(aggregateIdMock1, { + const response = await eventStorageAdapter.getEvents(aggregateIdMock1, { eventStoreId, }); expect(response).toStrictEqual({ events: [] }); }); it('throws an error if version already exists', async () => { - await storageAdapter.pushEvent(eventMock1, { eventStoreId }); + await eventStorageAdapter.pushEvent(eventMock1, { eventStoreId }); await expect(() => - storageAdapter.pushEvent(eventMock1, { eventStoreId }), + eventStorageAdapter.pushEvent(eventMock1, { eventStoreId }), ).rejects.toThrow(InMemoryEventAlreadyExistsError); }); it('overrides event is force option is set to true', async () => { - const { event } = await storageAdapter.pushEvent(eventMock1, { + const { event } = await eventStorageAdapter.pushEvent(eventMock1, { eventStoreId, force: true, }); @@ -71,39 +71,42 @@ describe('in-memory storage adapter', () => { it('pushes and gets events correctly', async () => { const { timestamp, ...eventMock2WithoutTimestamp } = eventMock2; MockDate.set(timestamp); - await storageAdapter.pushEvent(eventMock2WithoutTimestamp, { + await eventStorageAdapter.pushEvent(eventMock2WithoutTimestamp, { eventStoreId, }); MockDate.reset(); - const allEvents = await storageAdapter.getEvents(aggregateIdMock1, { - eventStoreId, - }); + const allEvents = await eventStorageAdapter.getEvents( + aggregateIdMock1, + { + eventStoreId, + }, + ); // Check that the timestamp is added expect(allEvents).toStrictEqual({ events: [eventMock1, eventMock2] }); - const eventsMaxVersion = await storageAdapter.getEvents( + const eventsMaxVersion = await eventStorageAdapter.getEvents( aggregateIdMock1, { eventStoreId }, { maxVersion: 1 }, ); expect(eventsMaxVersion).toStrictEqual({ events: [eventMock1] }); - const eventsMinVersion = await storageAdapter.getEvents( + const eventsMinVersion = await eventStorageAdapter.getEvents( aggregateIdMock1, { eventStoreId }, { minVersion: 2 }, ); expect(eventsMinVersion).toStrictEqual({ events: [eventMock2] }); - const eventsLimit = await storageAdapter.getEvents( + const eventsLimit = await eventStorageAdapter.getEvents( aggregateIdMock1, { eventStoreId }, { limit: 1 }, ); expect(eventsLimit).toStrictEqual({ events: [eventMock1] }); - const eventsReverse = await storageAdapter.getEvents( + const eventsReverse = await eventStorageAdapter.getEvents( aggregateIdMock1, { eventStoreId }, { reverse: true }, @@ -112,7 +115,7 @@ describe('in-memory storage adapter', () => { events: [eventMock2, eventMock1], }); - const eventsReverseAndLimit = await storageAdapter.getEvents( + const eventsReverseAndLimit = await eventStorageAdapter.getEvents( aggregateIdMock1, { eventStoreId }, { limit: 1, reverse: true }, @@ -122,12 +125,12 @@ describe('in-memory storage adapter', () => { }); describe('listAggregateIds', () => { - const storageAdapter = new InMemoryStorageAdapter(); + const eventStorageAdapter = new InMemoryEventStorageAdapter(); it('list aggregate Ids', async () => { - await storageAdapter.pushEvent(eventMock1, { eventStoreId }); + await eventStorageAdapter.pushEvent(eventMock1, { eventStoreId }); - await storageAdapter.pushEvent( + await eventStorageAdapter.pushEvent( { aggregateId: aggregateIdMock2, version: 1, @@ -137,7 +140,7 @@ describe('in-memory storage adapter', () => { { eventStoreId }, ); - const aggregateIds = await storageAdapter.listAggregateIds({ + const aggregateIds = await eventStorageAdapter.listAggregateIds({ eventStoreId, }); @@ -147,7 +150,7 @@ describe('in-memory storage adapter', () => { }); it('paginates aggregate Ids', async () => { - await storageAdapter.pushEvent( + await eventStorageAdapter.pushEvent( { aggregateId: aggregateIdMock3, version: 1, @@ -157,7 +160,7 @@ describe('in-memory storage adapter', () => { { eventStoreId }, ); - await storageAdapter.pushEvent( + await eventStorageAdapter.pushEvent( { aggregateId: aggregateIdMock4, version: 1, @@ -168,7 +171,10 @@ describe('in-memory storage adapter', () => { ); const { aggregateIds, nextPageToken } = - await storageAdapter.listAggregateIds({ eventStoreId }, { limit: 2 }); + await eventStorageAdapter.listAggregateIds( + { eventStoreId }, + { limit: 2 }, + ); expect(aggregateIds).toStrictEqual([ aggregateIdMock1, @@ -179,7 +185,7 @@ describe('in-memory storage adapter', () => { lastEvaluatedKey: aggregateIdMock2, }); - const lastAggregateIds = await storageAdapter.listAggregateIds( + const lastAggregateIds = await eventStorageAdapter.listAggregateIds( { eventStoreId }, { pageToken: nextPageToken }, ); @@ -191,7 +197,7 @@ describe('in-memory storage adapter', () => { it('applies lisAggregateIds options', async () => { const { aggregateIds, nextPageToken } = - await storageAdapter.listAggregateIds( + await eventStorageAdapter.listAggregateIds( { eventStoreId }, { limit: 1, @@ -211,7 +217,7 @@ describe('in-memory storage adapter', () => { }); const { aggregateIds: lastAggregateIds, nextPageToken: noPageToken } = - await storageAdapter.listAggregateIds( + await eventStorageAdapter.listAggregateIds( { eventStoreId }, { pageToken: nextPageToken }, ); @@ -222,28 +228,28 @@ describe('in-memory storage adapter', () => { }); describe('groupEvent', () => { - const storageAdapter = new InMemoryStorageAdapter(); + const eventStorageAdapter = new InMemoryEventStorageAdapter(); it('groups events correctly', () => { - const groupedEvent = storageAdapter.groupEvent( + const groupedEvent = eventStorageAdapter.groupEvent( omit(eventMock1, 'timestamp'), ); expect(groupedEvent).toBeInstanceOf(GroupedEvent); expect(groupedEvent).toMatchObject({ event: omit(eventMock1, 'timestamp'), - eventStorageAdapter: storageAdapter, + eventStorageAdapter: eventStorageAdapter, }); }); }); }); describe('pushEventGroup', () => { - const storageAdapterA = new InMemoryStorageAdapter(); - const storageAdapterB = new InMemoryStorageAdapter(); - // @ts-expect-error we don't care about the storage adapter, it just needs to not be an instance of InMemoryStorageAdapter - const storageAdapterC: StorageAdapter = {}; - storageAdapterC; + const eventStorageAdapterA = new InMemoryEventStorageAdapter(); + const eventStorageAdapterB = new InMemoryEventStorageAdapter(); + // @ts-expect-error we don't care about the storage adapter, it just needs to not be an instance of InMemoryEventStorageAdapter + const eventStorageAdapterC: EventStorageAdapter = {}; + eventStorageAdapterC; const aggregate2EventMock = { aggregateId: aggregateIdMock2, @@ -253,36 +259,38 @@ describe('in-memory storage adapter', () => { }; beforeEach(() => { - storageAdapterA.eventStore = {}; - storageAdapterB.eventStore = {}; + eventStorageAdapterA.eventStore = {}; + eventStorageAdapterB.eventStore = {}; }); it('push grouped events correctly', async () => { const groupedEvents: [GroupedEvent, ...GroupedEvent[]] = [ new GroupedEvent({ event: eventMock1, - eventStorageAdapter: storageAdapterA, + eventStorageAdapter: eventStorageAdapterA, context: { eventStoreId }, }), new GroupedEvent({ event: aggregate2EventMock, - eventStorageAdapter: storageAdapterB, + eventStorageAdapter: eventStorageAdapterB, context: { eventStoreId }, }), ]; - const eventGroup = await storageAdapterA.pushEventGroup(...groupedEvents); + const eventGroup = await eventStorageAdapterA.pushEventGroup( + ...groupedEvents, + ); expect(eventGroup).toStrictEqual({ eventGroup: [{ event: eventMock1 }, { event: aggregate2EventMock }], }); - const { events: eventsA } = await storageAdapterA.getEvents( + const { events: eventsA } = await eventStorageAdapterA.getEvents( aggregateIdMock1, { eventStoreId }, ); expect(eventsA).toStrictEqual([eventMock1]); - const { events: eventsB } = await storageAdapterB.getEvents( + const { events: eventsB } = await eventStorageAdapterB.getEvents( aggregateIdMock2, { eventStoreId }, ); @@ -293,18 +301,18 @@ describe('in-memory storage adapter', () => { const groupedEvents: [GroupedEvent, ...GroupedEvent[]] = [ new GroupedEvent({ event: eventMock1, - eventStorageAdapter: storageAdapterA, + eventStorageAdapter: eventStorageAdapterA, context: { eventStoreId }, }), new GroupedEvent({ event: aggregate2EventMock, - eventStorageAdapter: storageAdapterC, + eventStorageAdapter: eventStorageAdapterC, context: { eventStoreId }, }), ]; await expect(() => - storageAdapterA.pushEventGroup(...groupedEvents), + eventStorageAdapterA.pushEventGroup(...groupedEvents), ).rejects.toThrow(); }); @@ -312,17 +320,17 @@ describe('in-memory storage adapter', () => { const groupedEvents: [GroupedEvent, ...GroupedEvent[]] = [ new GroupedEvent({ event: eventMock1, - eventStorageAdapter: storageAdapterA, + eventStorageAdapter: eventStorageAdapterA, context: { eventStoreId }, }), new GroupedEvent({ event: aggregate2EventMock, - eventStorageAdapter: storageAdapterB, + eventStorageAdapter: eventStorageAdapterB, }), ]; await expect(() => - storageAdapterA.pushEventGroup(...groupedEvents), + eventStorageAdapterA.pushEventGroup(...groupedEvents), ).rejects.toThrow(); }); @@ -330,7 +338,7 @@ describe('in-memory storage adapter', () => { const groupedEvents: [GroupedEvent, ...GroupedEvent[]] = [ new GroupedEvent({ event: eventMock1, - eventStorageAdapter: storageAdapterA, + eventStorageAdapter: eventStorageAdapterA, context: { eventStoreId }, }), new GroupedEvent({ @@ -338,19 +346,19 @@ describe('in-memory storage adapter', () => { ...aggregate2EventMock, timestamp: new Date().toISOString(), }, - eventStorageAdapter: storageAdapterB, + eventStorageAdapter: eventStorageAdapterB, }), ]; await expect(() => - storageAdapterA.pushEventGroup(...groupedEvents), + eventStorageAdapterA.pushEventGroup(...groupedEvents), ).rejects.toThrow(); }); it('reverts all events if a push has failed', async () => { - const pushEventSyncASpy = vi.spyOn(storageAdapterA, 'pushEventSync'); + const pushEventSyncASpy = vi.spyOn(eventStorageAdapterA, 'pushEventSync'); const pushEventSyncBSpy = vi - .spyOn(storageAdapterB, 'pushEventSync') + .spyOn(eventStorageAdapterB, 'pushEventSync') .mockImplementation(() => { throw new Error(); }); @@ -358,30 +366,30 @@ describe('in-memory storage adapter', () => { const groupedEvents: [GroupedEvent, ...GroupedEvent[]] = [ new GroupedEvent({ event: eventMock1, - eventStorageAdapter: storageAdapterA, + eventStorageAdapter: eventStorageAdapterA, context: { eventStoreId }, }), new GroupedEvent({ event: aggregate2EventMock, - eventStorageAdapter: storageAdapterB, + eventStorageAdapter: eventStorageAdapterB, context: { eventStoreId }, }), ]; await expect(() => - storageAdapterA.pushEventGroup(...groupedEvents), + eventStorageAdapterA.pushEventGroup(...groupedEvents), ).rejects.toThrow(); expect(pushEventSyncASpy).toHaveBeenCalledOnce(); expect(pushEventSyncBSpy).toHaveBeenCalledOnce(); - const { events: eventsA } = await storageAdapterA.getEvents( + const { events: eventsA } = await eventStorageAdapterA.getEvents( aggregateIdMock1, { eventStoreId }, ); expect(eventsA).toStrictEqual([]); - const { events: eventsB } = await storageAdapterB.getEvents( + const { events: eventsB } = await eventStorageAdapterB.getEvents( aggregateIdMock2, { eventStoreId }, ); diff --git a/packages/json-schema-command/src/command.fixtures.test.ts b/packages/json-schema-command/src/command.fixtures.test.ts index 41e7c746..d27e9b2b 100644 --- a/packages/json-schema-command/src/command.fixtures.test.ts +++ b/packages/json-schema-command/src/command.fixtures.test.ts @@ -5,7 +5,7 @@ import { EventStore, EventType, EventTypeDetail, - StorageAdapter, + EventStorageAdapter, tuple, } from '@castore/core'; @@ -20,7 +20,7 @@ export const putSnapshotMock = vi.fn(); export const getLastSnapshotMock = vi.fn(); export const listSnapshotsMock = vi.fn(); -export const mockStorageAdapter: StorageAdapter = { +export const eventStorageAdapterMock: EventStorageAdapter = { pushEvent: pushEventMock, pushEventGroup: pushEventGroupMock, groupEvent: groupEvent, @@ -99,7 +99,7 @@ export const counterEventStore = new EventStore({ counterDeletedEvent, ], reduce: countersReducer, - storageAdapter: mockStorageAdapter, + eventStorageAdapter: eventStorageAdapterMock, }); export const inputSchema = { diff --git a/packages/redux-event-storage-adapter/README.md b/packages/redux-event-storage-adapter/README.md index 9450fc6d..02e7535c 100644 --- a/packages/redux-event-storage-adapter/README.md +++ b/packages/redux-event-storage-adapter/README.md @@ -44,7 +44,7 @@ const MyReactApp = () => ( ); ``` -And that's it 🙌 `configureCastore` not only configures the Redux store but also connects it to the event stores by replacing their `storageAdapter`. +And that's it 🙌 `configureCastore` not only configures the Redux store but also connects it to the event stores by replacing their `eventStorageAdapter`. You can use the `pushEvent` method as usual: @@ -121,7 +121,7 @@ const store = configureStore({ // 👇 Connect the event stores to the store eventStores.forEach(eventStore => { - eventStore.storageAdapter = new ReduxEventStorageAdapter({ + eventStore.eventStorageAdapter = new ReduxEventStorageAdapter({ store, eventStoreId: eventStore.eventStoreId, // 👇 Don't forget the prefix if one has been provided diff --git a/packages/redux-event-storage-adapter/src/adapter.ts b/packages/redux-event-storage-adapter/src/adapter.ts index 6cd538ec..214b1e67 100644 --- a/packages/redux-event-storage-adapter/src/adapter.ts +++ b/packages/redux-event-storage-adapter/src/adapter.ts @@ -3,7 +3,7 @@ import type { EnhancedStore } from '@reduxjs/toolkit'; import { GroupedEvent, - StorageAdapter, + EventStorageAdapter, EventDetail, PushEventOptions, Aggregate, @@ -11,7 +11,7 @@ import { import { ReduxStoreEventAlreadyExistsError, - EventStoreReduxStateNotFoundError, + ReduxStateNotFoundError, } from '~/errors'; import type { EventStoreReduxState, EventStoresReduxState } from './types'; @@ -28,7 +28,7 @@ type ReduxGroupedEvent< eventStorageAdapter: ReduxEventStorageAdapter; }; -const hasReduxStorageAdapter = ( +const hasReduxEventStorageAdapter = ( groupedEvent: GroupedEvent, ): groupedEvent is ReduxGroupedEvent => groupedEvent.eventStorageAdapter instanceof ReduxEventStorageAdapter; @@ -55,7 +55,7 @@ const parseGroupedEvents = ( })[] = []; groupedEventsInput.forEach((groupedEvent, groupedEventIndex) => { - if (!hasReduxStorageAdapter(groupedEvent)) { + if (!hasReduxEventStorageAdapter(groupedEvent)) { throw new Error( `Event group event #${groupedEventIndex} is not connected to a ReduxEventStorageAdapter`, ); @@ -102,19 +102,19 @@ const parseGroupedEvents = ( }; }; -export class ReduxEventStorageAdapter implements StorageAdapter { - getEvents: StorageAdapter['getEvents']; +export class ReduxEventStorageAdapter implements EventStorageAdapter { + getEvents: EventStorageAdapter['getEvents']; pushEventSync: ( eventDetail: EventDetail, options: PushEventOptions, - ) => Awaited>; - pushEvent: StorageAdapter['pushEvent']; - pushEventGroup: StorageAdapter['pushEventGroup']; - groupEvent: StorageAdapter['groupEvent']; - listAggregateIds: StorageAdapter['listAggregateIds']; - putSnapshot: StorageAdapter['putSnapshot']; - getLastSnapshot: StorageAdapter['getLastSnapshot']; - listSnapshots: StorageAdapter['listSnapshots']; + ) => Awaited>; + pushEvent: EventStorageAdapter['pushEvent']; + pushEventGroup: EventStorageAdapter['pushEventGroup']; + groupEvent: EventStorageAdapter['groupEvent']; + listAggregateIds: EventStorageAdapter['listAggregateIds']; + putSnapshot: EventStorageAdapter['putSnapshot']; + getLastSnapshot: EventStorageAdapter['getLastSnapshot']; + listSnapshots: EventStorageAdapter['listSnapshots']; store: EnhancedStore; eventStoreId: string; @@ -140,7 +140,7 @@ export class ReduxEventStorageAdapter implements StorageAdapter { const eventStoreState = this.store.getState()[eventStoreSliceName]; if (eventStoreState === undefined) - throw new EventStoreReduxStateNotFoundError({ eventStoreSliceName }); + throw new ReduxStateNotFoundError({ eventStoreSliceName }); return eventStoreState; }; @@ -198,13 +198,13 @@ export class ReduxEventStorageAdapter implements StorageAdapter { .reverse() .forEach(groupedEventToRevert => { const { - eventStorageAdapter: eventToRevertStorageAdapter, + eventStorageAdapter: eventToRevertEventStorageAdapter, event: eventToRevert, } = groupedEventToRevert; const { aggregateId, version } = eventToRevert; - eventToRevertStorageAdapter.store.dispatch({ - type: `${eventToRevertStorageAdapter.eventStoreSliceName}/eventReverted`, + eventToRevertEventStorageAdapter.store.dispatch({ + type: `${eventToRevertEventStorageAdapter.eventStoreSliceName}/eventReverted`, payload: { aggregateId, version }, }); }); diff --git a/packages/redux-event-storage-adapter/src/configureCastore.ts b/packages/redux-event-storage-adapter/src/configureCastore.ts index faf79190..8e8d8453 100644 --- a/packages/redux-event-storage-adapter/src/configureCastore.ts +++ b/packages/redux-event-storage-adapter/src/configureCastore.ts @@ -19,7 +19,7 @@ export const configureCastore = ({ const store = configureStore({ reducer: castoreReducers }); eventStores.forEach(eventStore => { - eventStore.storageAdapter = new ReduxEventStorageAdapter({ + eventStore.eventStorageAdapter = new ReduxEventStorageAdapter({ store, eventStoreId: eventStore.eventStoreId, prefix, diff --git a/packages/redux-event-storage-adapter/src/errors/index.ts b/packages/redux-event-storage-adapter/src/errors/index.ts index d9a28ea9..2003bebd 100644 --- a/packages/redux-event-storage-adapter/src/errors/index.ts +++ b/packages/redux-event-storage-adapter/src/errors/index.ts @@ -1,3 +1,3 @@ export { ReduxStoreEventAlreadyExistsError } from './reduxStoreEventAlreadyExists'; -export { EventStoreReduxStateNotFoundError } from './eventStoreReduxStateNotFound'; -export { EventStoreReduxStorageAdapterNotFoundError } from './reduxEventStorageAdapterNotFound'; +export { ReduxStateNotFoundError } from './reduxStateNotFound'; +export { ReduxEventStorageAdapterNotFoundError } from './reduxEventStorageAdapterNotFound'; diff --git a/packages/redux-event-storage-adapter/src/errors/reduxEventStorageAdapterNotFound.ts b/packages/redux-event-storage-adapter/src/errors/reduxEventStorageAdapterNotFound.ts index abc16909..fb5f6edb 100644 --- a/packages/redux-event-storage-adapter/src/errors/reduxEventStorageAdapterNotFound.ts +++ b/packages/redux-event-storage-adapter/src/errors/reduxEventStorageAdapterNotFound.ts @@ -1,4 +1,4 @@ -export class EventStoreReduxStorageAdapterNotFoundError extends Error { +export class ReduxEventStorageAdapterNotFoundError extends Error { eventStoreId: string; constructor({ eventStoreId }: { eventStoreId: string }) { diff --git a/packages/redux-event-storage-adapter/src/errors/eventStoreReduxStateNotFound.ts b/packages/redux-event-storage-adapter/src/errors/reduxStateNotFound.ts similarity index 79% rename from packages/redux-event-storage-adapter/src/errors/eventStoreReduxStateNotFound.ts rename to packages/redux-event-storage-adapter/src/errors/reduxStateNotFound.ts index e5c38360..d275daae 100644 --- a/packages/redux-event-storage-adapter/src/errors/eventStoreReduxStateNotFound.ts +++ b/packages/redux-event-storage-adapter/src/errors/reduxStateNotFound.ts @@ -1,4 +1,4 @@ -export class EventStoreReduxStateNotFoundError extends Error { +export class ReduxStateNotFoundError extends Error { eventStoreSliceName: string; constructor({ eventStoreSliceName }: { eventStoreSliceName: string }) { diff --git a/packages/redux-event-storage-adapter/src/hooks/useAggregateEvents.ts b/packages/redux-event-storage-adapter/src/hooks/useAggregateEvents.ts index fd6c4051..ca84c68c 100644 --- a/packages/redux-event-storage-adapter/src/hooks/useAggregateEvents.ts +++ b/packages/redux-event-storage-adapter/src/hooks/useAggregateEvents.ts @@ -7,8 +7,8 @@ import { } from '@castore/core'; import { ReduxEventStorageAdapter } from '~/adapter'; -import { EventStoreReduxStateNotFoundError } from '~/errors/eventStoreReduxStateNotFound'; -import { EventStoreReduxStorageAdapterNotFoundError } from '~/errors/reduxEventStorageAdapterNotFound'; +import { ReduxEventStorageAdapterNotFoundError } from '~/errors/reduxEventStorageAdapterNotFound'; +import { ReduxStateNotFoundError } from '~/errors/reduxStateNotFound'; import { EventStoresReduxState } from '~/types'; export const useAggregateEvents = ( @@ -17,19 +17,19 @@ export const useAggregateEvents = ( { minVersion, maxVersion, reverse, limit }: EventsQueryOptions = {}, ): { events: EventStoreEventsDetails[] } => { let events = (useSelector(state => { - const storageAdapter = eventStore.getStorageAdapter(); + const eventStorageAdapter = eventStore.getEventStorageAdapter(); - if (!(storageAdapter instanceof ReduxEventStorageAdapter)) { - throw new EventStoreReduxStorageAdapterNotFoundError({ + if (!(eventStorageAdapter instanceof ReduxEventStorageAdapter)) { + throw new ReduxEventStorageAdapterNotFoundError({ eventStoreId: eventStore.eventStoreId, }); } - const eventStoreSliceName = storageAdapter.eventStoreSliceName; + const eventStoreSliceName = eventStorageAdapter.eventStoreSliceName; const eventStoreState = state[eventStoreSliceName]; if (!eventStoreState) { - throw new EventStoreReduxStateNotFoundError({ eventStoreSliceName }); + throw new ReduxStateNotFoundError({ eventStoreSliceName }); } return eventStoreState.eventsByAggregateId[aggregateId]; diff --git a/packages/redux-event-storage-adapter/src/hooks/useAggregateIds.ts b/packages/redux-event-storage-adapter/src/hooks/useAggregateIds.ts index 8314e5b1..6c40cc4c 100644 --- a/packages/redux-event-storage-adapter/src/hooks/useAggregateIds.ts +++ b/packages/redux-event-storage-adapter/src/hooks/useAggregateIds.ts @@ -7,8 +7,8 @@ import { } from '@castore/core'; import { ReduxEventStorageAdapter } from '~/adapter'; -import { EventStoreReduxStateNotFoundError } from '~/errors/eventStoreReduxStateNotFound'; -import { EventStoreReduxStorageAdapterNotFoundError } from '~/errors/reduxEventStorageAdapterNotFound'; +import { ReduxEventStorageAdapterNotFoundError } from '~/errors/reduxEventStorageAdapterNotFound'; +import { ReduxStateNotFoundError } from '~/errors/reduxStateNotFound'; import { EventStoreReduxState } from '~/types'; import { parseAppliedListAggregateIdsOptions, @@ -23,19 +23,19 @@ export const useAggregateIds = ( const storeAggregateEntries = (useSelector< Record> >(state => { - const storageAdapter = eventStore.getStorageAdapter(); + const eventStorageAdapter = eventStore.getEventStorageAdapter(); - if (!(storageAdapter instanceof ReduxEventStorageAdapter)) { - throw new EventStoreReduxStorageAdapterNotFoundError({ + if (!(eventStorageAdapter instanceof ReduxEventStorageAdapter)) { + throw new ReduxEventStorageAdapterNotFoundError({ eventStoreId: eventStore.eventStoreId, }); } - const eventStoreSliceName = storageAdapter.eventStoreSliceName; + const eventStoreSliceName = eventStorageAdapter.eventStoreSliceName; const eventStoreState = state[eventStoreSliceName]; if (!eventStoreState) { - throw new EventStoreReduxStateNotFoundError({ eventStoreSliceName }); + throw new ReduxStateNotFoundError({ eventStoreSliceName }); } return eventStoreState.aggregateIds; diff --git a/packages/test-tools/README.md b/packages/test-tools/README.md index ef9893b3..129f2074 100644 --- a/packages/test-tools/README.md +++ b/packages/test-tools/README.md @@ -26,7 +26,7 @@ yarn add @castore/core ### MockEventStore -The `mockEventStore` util returns a copy of the provided `EventStore` connected to an [`InMemoryStorageAdapter`](https://github.com/castore-dev/castore/tree/main/packages/inmemory-event-storage-adapter), empty or with a given initial state. It follows the `EventStore` interface but adds a `reset` method to reset it to the provided initial state. The original event store is not muted. +The `mockEventStore` util returns a copy of the provided `EventStore` connected to an [`InMemoryEventStorageAdapter`](https://github.com/castore-dev/castore/tree/main/packages/inmemory-event-storage-adapter), empty or with a given initial state. It follows the `EventStore` interface but adds a `reset` method to reset it to the provided initial state. The original event store is not muted. ```ts import { EventStore } from '@castore/core'; @@ -71,7 +71,7 @@ describe('My awesome test', () => { ### MuteEventStore -Unlike `mockEventStore`, the `muteEventStore` util mutes the original event store and replace its storage adapter with an `InMemoryStorageAdapter` matching the provided initial state. +Unlike `mockEventStore`, the `muteEventStore` util mutes the original event store and replace its storage adapter with an `InMemoryEventStorageAdapter` matching the provided initial state. ```ts import { EventStore } from '@castore/core'; diff --git a/packages/test-tools/src/mockEventStore.unit.test.ts b/packages/test-tools/src/mockEventStore.unit.test.ts index c7a24ed0..24048730 100644 --- a/packages/test-tools/src/mockEventStore.unit.test.ts +++ b/packages/test-tools/src/mockEventStore.unit.test.ts @@ -13,7 +13,7 @@ describe('mockEventStore', () => { ]); it('does not mutate the original event store', () => { - expect(pokemonsEventStore.storageAdapter).toBeUndefined(); + expect(pokemonsEventStore.eventStorageAdapter).toBeUndefined(); }); it('gives the event store an in memory storage adapter and pushes the events', async () => { diff --git a/packages/test-tools/src/mockedEventStore.ts b/packages/test-tools/src/mockedEventStore.ts index 1614537a..c82b1ed5 100644 --- a/packages/test-tools/src/mockedEventStore.ts +++ b/packages/test-tools/src/mockedEventStore.ts @@ -7,7 +7,7 @@ import { Reducer, $Contravariant, } from '@castore/core'; -import { InMemoryStorageAdapter } from '@castore/inmemory-event-storage-adapter'; +import { InMemoryEventStorageAdapter } from '@castore/inmemory-event-storage-adapter'; export class MockedEventStore< EVENT_STORE_ID extends string = string, @@ -49,11 +49,13 @@ export class MockedEventStore< eventStoreEvents: eventStore.eventStoreEvents, reduce: eventStore.reduce, simulateSideEffect: eventStore.simulateSideEffect, - storageAdapter: new InMemoryStorageAdapter({ initialEvents }), + eventStorageAdapter: new InMemoryEventStorageAdapter({ initialEvents }), }); this.initialEvents = initialEvents; this.reset = () => - (this.storageAdapter = new InMemoryStorageAdapter({ initialEvents })); + (this.eventStorageAdapter = new InMemoryEventStorageAdapter({ + initialEvents, + })); } } diff --git a/packages/test-tools/src/muteEventStore.ts b/packages/test-tools/src/muteEventStore.ts index fdbc60c0..20df583c 100644 --- a/packages/test-tools/src/muteEventStore.ts +++ b/packages/test-tools/src/muteEventStore.ts @@ -1,9 +1,11 @@ import { EventStore, EventStoreEventsDetails } from '@castore/core'; -import { InMemoryStorageAdapter } from '@castore/inmemory-event-storage-adapter'; +import { InMemoryEventStorageAdapter } from '@castore/inmemory-event-storage-adapter'; export const muteEventStore = ( eventStore: EVENT_STORE, initialEvents: EventStoreEventsDetails[] = [], ): void => { - eventStore.storageAdapter = new InMemoryStorageAdapter({ initialEvents }); + eventStore.eventStorageAdapter = new InMemoryEventStorageAdapter({ + initialEvents, + }); }; diff --git a/packages/test-tools/src/muteEventStore.unit.test.ts b/packages/test-tools/src/muteEventStore.unit.test.ts index 49b6f5bd..3fac36c4 100644 --- a/packages/test-tools/src/muteEventStore.unit.test.ts +++ b/packages/test-tools/src/muteEventStore.unit.test.ts @@ -11,7 +11,7 @@ describe('muteEventStore', () => { muteEventStore(pokemonsEventStore, [pikachuAppearedEvent]); it('does mutate the original event store', () => { - expect(pokemonsEventStore.storageAdapter).not.toBeUndefined(); + expect(pokemonsEventStore.eventStorageAdapter).not.toBeUndefined(); }); it('gives the event store an in memory storage adapter and pushes the events', async () => { From e55f55a6a9a75569ce7e21c4bb52ad0915cd9547 Mon Sep 17 00:00:00 2001 From: Thomas Aribart Date: Fri, 29 Sep 2023 17:56:03 +0200 Subject: [PATCH 2/5] rename EventTypesDetails to EventTypeDetails --- docs/docs/2-event-sourcing/1-events.md | 6 +++--- .../core/src/connectedEventStore/connectedEventStore.ts | 4 ++-- packages/core/src/event/eventType.ts | 5 +---- packages/core/src/event/eventType.type.test.ts | 4 ++-- packages/core/src/eventStore/eventStore.ts | 4 ++-- packages/core/src/index.ts | 2 +- packages/test-tools/src/mockedEventStore.ts | 4 ++-- 7 files changed, 13 insertions(+), 16 deletions(-) diff --git a/docs/docs/2-event-sourcing/1-events.md b/docs/docs/2-event-sourcing/1-events.md index 6d743012..47daf7b2 100644 --- a/docs/docs/2-event-sourcing/1-events.md +++ b/docs/docs/2-event-sourcing/1-events.md @@ -109,12 +109,12 @@ type PokemonCaughtEventTypeDetail = { }; ``` -- `EventTypesDetails`: Returns the events details of a list of `EventType` +- `EventTypeDetails`: Returns the events details of a list of `EventType` ```ts -import type { EventTypesDetails } from '@castore/core'; +import type { EventTypeDetails } from '@castore/core'; -type PokemonEventTypeDetails = EventTypesDetails< +type PokemonEventTypeDetails = EventTypeDetails< [typeof pokemonAppearedEventType, typeof pokemonCaughtEventType] >; // => EventTypeDetail diff --git a/packages/core/src/connectedEventStore/connectedEventStore.ts b/packages/core/src/connectedEventStore/connectedEventStore.ts index dbe64df5..64d11501 100644 --- a/packages/core/src/connectedEventStore/connectedEventStore.ts +++ b/packages/core/src/connectedEventStore/connectedEventStore.ts @@ -1,6 +1,6 @@ import type { Aggregate } from '~/aggregate'; import type { EventDetail } from '~/event/eventDetail'; -import type { EventType, EventTypesDetails } from '~/event/eventType'; +import type { EventType, EventTypeDetails } from '~/event/eventType'; import type { EventStorageAdapter } from '~/eventStorageAdapter'; import type { Reducer, @@ -22,7 +22,7 @@ import { publishPushedEvent } from './publishPushedEvent'; export class ConnectedEventStore< EVENT_STORE_ID extends string = string, EVENT_TYPES extends EventType[] = EventType[], - EVENT_DETAIL extends EventDetail = EventTypesDetails, + EVENT_DETAIL extends EventDetail = EventTypeDetails, $EVENT_DETAIL extends EventDetail = $Contravariant, REDUCER extends Reducer = Reducer< Aggregate, diff --git a/packages/core/src/event/eventType.ts b/packages/core/src/event/eventType.ts index 860d043b..10779ee4 100644 --- a/packages/core/src/event/eventType.ts +++ b/packages/core/src/event/eventType.ts @@ -19,10 +19,7 @@ export type EventTypeDetail = NonNullable< EVENT_TYPE['_types'] >['detail']; -/** - * @debt v2 "rename as EventTypeDetails" - */ -export type EventTypesDetails = +export type EventTypeDetails = EVENT_TYPES[number] extends infer EVENT_TYPE ? EVENT_TYPE extends EventType ? EventTypeDetail diff --git a/packages/core/src/event/eventType.type.test.ts b/packages/core/src/event/eventType.type.test.ts index bc3a8799..eba024d0 100644 --- a/packages/core/src/event/eventType.type.test.ts +++ b/packages/core/src/event/eventType.type.test.ts @@ -1,6 +1,6 @@ import type { A } from 'ts-toolbelt'; -import { EventType, EventTypeDetail, EventTypesDetails } from './eventType'; +import { EventType, EventTypeDetail, EventTypeDetails } from './eventType'; // Payload, no metadata @@ -66,7 +66,7 @@ const eventTypes = [ counterRemovedEvent, ]; -type CounterEventDetail = EventTypesDetails; +type CounterEventDetail = EventTypeDetails; const assertDetails: A.Equals< CounterEventDetail, | EventTypeDetail diff --git a/packages/core/src/eventStore/eventStore.ts b/packages/core/src/eventStore/eventStore.ts index 08224fb1..e539c6e0 100644 --- a/packages/core/src/eventStore/eventStore.ts +++ b/packages/core/src/eventStore/eventStore.ts @@ -1,7 +1,7 @@ /* eslint-disable max-lines */ import type { Aggregate } from '~/aggregate'; import type { EventDetail } from '~/event/eventDetail'; -import type { EventType, EventTypesDetails } from '~/event/eventType'; +import type { EventType, EventTypeDetails } from '~/event/eventType'; import type { GroupedEvent } from '~/event/groupedEvent'; import type { EventStorageAdapter } from '~/eventStorageAdapter'; import type { $Contravariant } from '~/utils'; @@ -25,7 +25,7 @@ import type { export class EventStore< EVENT_STORE_ID extends string = string, EVENT_TYPES extends EventType[] = EventType[], - EVENT_DETAILS extends EventDetail = EventTypesDetails, + EVENT_DETAILS extends EventDetail = EventTypeDetails, // cf https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-rc/#optional-variance-annotations-for-type-parameters // EventStore is contravariant on its fns args: We have to type them as "any" so that EventStore implementations still extends the EventStore type $EVENT_DETAILS extends EventDetail = $Contravariant< diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index d0e494c8..2439ad24 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,6 +1,6 @@ export type { Aggregate } from './aggregate'; export { EventType } from './event/eventType'; -export type { EventTypeDetail, EventTypesDetails } from './event/eventType'; +export type { EventTypeDetail, EventTypeDetails } from './event/eventType'; export { GroupedEvent } from './event/groupedEvent'; export type { EventDetail, OptionalTimestamp } from './event/eventDetail'; export type { EventStorageAdapter } from './eventStorageAdapter'; diff --git a/packages/test-tools/src/mockedEventStore.ts b/packages/test-tools/src/mockedEventStore.ts index c82b1ed5..303f1108 100644 --- a/packages/test-tools/src/mockedEventStore.ts +++ b/packages/test-tools/src/mockedEventStore.ts @@ -3,7 +3,7 @@ import { EventDetail, EventStore, EventType, - EventTypesDetails, + EventTypeDetails, Reducer, $Contravariant, } from '@castore/core'; @@ -12,7 +12,7 @@ import { InMemoryEventStorageAdapter } from '@castore/inmemory-event-storage-ada export class MockedEventStore< EVENT_STORE_ID extends string = string, EVENT_TYPES extends EventType[] = EventType[], - EVENT_DETAIL extends EventDetail = EventTypesDetails, + EVENT_DETAIL extends EventDetail = EventTypeDetails, $EVENT_DETAIL extends EventDetail = $Contravariant, REDUCER extends Reducer = Reducer< Aggregate, From 9ebeb0560bd80f8351700ad420b6777f6ecba7a8 Mon Sep 17 00:00:00 2001 From: Thomas Aribart Date: Fri, 29 Sep 2023 18:03:37 +0200 Subject: [PATCH 3/5] rename reduce to reducer --- demo/blueprint/src/pokemons/eventStore.ts | 2 +- demo/blueprint/src/trainers/eventStore.ts | 2 +- docs/docs/2-event-sourcing/3-event-stores.md | 2 +- .../2-event-sourcing/4-fetching-events.md | 2 +- .../core/src/command/command.fixtures.test.ts | 2 +- .../connectedEventStore.ts | 4 ++-- .../eventStore/eventStore.fixtures.test.ts | 2 +- packages/core/src/eventStore/eventStore.ts | 20 +++++++------------ .../src/eventStore/eventStore.unit.test.ts | 2 +- packages/core/src/eventStore/generics.ts | 2 +- .../src/command.fixtures.test.ts | 2 +- packages/test-tools/src/mockedEventStore.ts | 2 +- 12 files changed, 19 insertions(+), 25 deletions(-) diff --git a/demo/blueprint/src/pokemons/eventStore.ts b/demo/blueprint/src/pokemons/eventStore.ts index 5069cceb..954a5c77 100644 --- a/demo/blueprint/src/pokemons/eventStore.ts +++ b/demo/blueprint/src/pokemons/eventStore.ts @@ -6,7 +6,7 @@ import { appearedEvent, caughtByTrainerEvent, levelledUpEvent } from './events'; export const pokemonsEventStore = new EventStore({ eventStoreId: 'POKEMONS', eventStoreEvents: [appearedEvent, caughtByTrainerEvent, levelledUpEvent], - reduce: (pokemonAggregate: PokemonAggregate, event): PokemonAggregate => { + reducer: (pokemonAggregate: PokemonAggregate, event): PokemonAggregate => { const { version, aggregateId } = event; switch (event.type) { diff --git a/demo/blueprint/src/trainers/eventStore.ts b/demo/blueprint/src/trainers/eventStore.ts index 1cba0e9d..a99d64ed 100644 --- a/demo/blueprint/src/trainers/eventStore.ts +++ b/demo/blueprint/src/trainers/eventStore.ts @@ -6,7 +6,7 @@ import { gameStartedEvent, pokemonCaughtEvent } from './events'; export const trainersEventStore = new EventStore({ eventStoreId: 'TRAINERS', eventStoreEvents: [gameStartedEvent, pokemonCaughtEvent], - reduce: (trainerAggregate: TrainerAggregate, event): TrainerAggregate => { + reducer: (trainerAggregate: TrainerAggregate, event): TrainerAggregate => { const { version, aggregateId } = event; switch (event.type) { diff --git a/docs/docs/2-event-sourcing/3-event-stores.md b/docs/docs/2-event-sourcing/3-event-stores.md index 25cb18d9..61a6b0e6 100644 --- a/docs/docs/2-event-sourcing/3-event-stores.md +++ b/docs/docs/2-event-sourcing/3-event-stores.md @@ -32,7 +32,7 @@ const pokemonsEventStore = new EventStore({ pokemonLeveledUpEventType, ... ], - reduce: pokemonsReducer, + reducer: pokemonsReducer, }); // ...and that's it 🥳 ``` diff --git a/docs/docs/2-event-sourcing/4-fetching-events.md b/docs/docs/2-event-sourcing/4-fetching-events.md index 417f9b77..eff84205 100644 --- a/docs/docs/2-event-sourcing/4-fetching-events.md +++ b/docs/docs/2-event-sourcing/4-fetching-events.md @@ -15,7 +15,7 @@ await pokemonsEventStore.getEvents('pikachu1'); const pokemonsEventStore = new EventStore({ eventStoreId: 'POKEMONS', eventTypes: pokemonEventTypes, - reduce: pokemonsReducer, + reducer: pokemonsReducer, // 👇 Provide it in the constructor eventStorageAdapter: mySuperEventStorageAdapter, }); diff --git a/packages/core/src/command/command.fixtures.test.ts b/packages/core/src/command/command.fixtures.test.ts index d0ff37eb..e4c8d052 100644 --- a/packages/core/src/command/command.fixtures.test.ts +++ b/packages/core/src/command/command.fixtures.test.ts @@ -115,7 +115,7 @@ export const counterEventStore = new EventStore({ counterIncrementedEvent, counterDeletedEvent, ], - reduce: countersReducer, + reducer: countersReducer, eventStorageAdapter: eventStorageAdapterMock, }); diff --git a/packages/core/src/connectedEventStore/connectedEventStore.ts b/packages/core/src/connectedEventStore/connectedEventStore.ts index 64d11501..0e408c78 100644 --- a/packages/core/src/connectedEventStore/connectedEventStore.ts +++ b/packages/core/src/connectedEventStore/connectedEventStore.ts @@ -74,7 +74,7 @@ export class ConnectedEventStore< }; eventStoreId: EVENT_STORE_ID; eventStoreEvents: EVENT_TYPES; - reduce: REDUCER; + reducer: REDUCER; simulateSideEffect: SideEffectsSimulator; getEvents: EventsGetter; pushEvent: EventPusher; @@ -114,7 +114,7 @@ export class ConnectedEventStore< ) { this.eventStoreId = eventStore.eventStoreId; this.eventStoreEvents = eventStore.eventStoreEvents; - this.reduce = eventStore.reduce; + this.reducer = eventStore.reducer; this.simulateSideEffect = eventStore.simulateSideEffect; this.getEvents = eventStore.getEvents; this.groupEvent = eventStore.groupEvent; diff --git a/packages/core/src/eventStore/eventStore.fixtures.test.ts b/packages/core/src/eventStore/eventStore.fixtures.test.ts index a6a93230..41f61103 100644 --- a/packages/core/src/eventStore/eventStore.fixtures.test.ts +++ b/packages/core/src/eventStore/eventStore.fixtures.test.ts @@ -119,6 +119,6 @@ export const pokemonsEventStore = new EventStore({ pokemonCaughtEvent, pokemonLeveledUpEvent, ], - reduce: pokemonsReducer, + reducer: pokemonsReducer, eventStorageAdapter: eventStorageAdapterMock, }); diff --git a/packages/core/src/eventStore/eventStore.ts b/packages/core/src/eventStore/eventStore.ts index e539c6e0..5d3b199e 100644 --- a/packages/core/src/eventStore/eventStore.ts +++ b/packages/core/src/eventStore/eventStore.ts @@ -63,7 +63,7 @@ export class EventStore< (prevAggregate || event.version === 1) && groupedEvent?.eventStore !== undefined ) { - nextAggregate = groupedEvent.eventStore.reduce(prevAggregate, event); + nextAggregate = groupedEvent.eventStore.reducer(prevAggregate, event); } return { event, ...(nextAggregate ? { nextAggregate } : {}) }; @@ -94,10 +94,7 @@ export class EventStore< * @debt v2 "rename as eventTypes" */ eventStoreEvents: EVENT_TYPES; - /** - * @debt v2 "rename as reducer" - */ - reduce: REDUCER; + reducer: REDUCER; simulateSideEffect: SideEffectsSimulator; getEvents: EventsGetter; @@ -125,7 +122,7 @@ export class EventStore< constructor({ eventStoreId, eventStoreEvents, - reduce, + reducer, simulateSideEffect = (indexedEvents, event) => ({ ...indexedEvents, [event.version]: event, @@ -137,16 +134,13 @@ export class EventStore< * @debt v2 "rename as eventTypes" */ eventStoreEvents: EVENT_TYPES; - /** - * @debt v2 "rename as reducer" - */ - reduce: REDUCER; + reducer: REDUCER; simulateSideEffect?: SideEffectsSimulator; eventStorageAdapter?: EventStorageAdapter; }) { this.eventStoreId = eventStoreId; this.eventStoreEvents = eventStoreEvents; - this.reduce = reduce; + this.reducer = reducer; this.simulateSideEffect = simulateSideEffect; this.eventStorageAdapter = $eventStorageAdapter; @@ -183,7 +177,7 @@ export class EventStore< let nextAggregate: AGGREGATE | undefined = undefined; if (prevAggregate || event.version === 1) { - nextAggregate = this.reduce(prevAggregate, event) as AGGREGATE; + nextAggregate = this.reducer(prevAggregate, event) as AGGREGATE; } const response = { @@ -227,7 +221,7 @@ export class EventStore< ); this.buildAggregate = (eventDetails, aggregate) => - eventDetails.reduce(this.reduce, aggregate) as AGGREGATE | undefined; + eventDetails.reduce(this.reducer, aggregate) as AGGREGATE | undefined; this.getAggregate = async (aggregateId, { maxVersion } = {}) => { const { events } = await this.getEvents(aggregateId, { maxVersion }); diff --git a/packages/core/src/eventStore/eventStore.unit.test.ts b/packages/core/src/eventStore/eventStore.unit.test.ts index d7a066e5..9c18d87e 100644 --- a/packages/core/src/eventStore/eventStore.unit.test.ts +++ b/packages/core/src/eventStore/eventStore.unit.test.ts @@ -43,7 +43,7 @@ describe('event store', () => { new Set([ 'eventStoreId', 'eventStoreEvents', - 'reduce', + 'reducer', 'simulateSideEffect', 'eventStorageAdapter', 'getEventStorageAdapter', diff --git a/packages/core/src/eventStore/generics.ts b/packages/core/src/eventStore/generics.ts index e0f5ea2d..45392b0f 100644 --- a/packages/core/src/eventStore/generics.ts +++ b/packages/core/src/eventStore/generics.ts @@ -16,7 +16,7 @@ export type EventStoreEventsDetails = NonNullable['details']; export type EventStoreReducer = - EVENT_STORE['reduce']; + EVENT_STORE['reducer']; export type EventStoreAggregate = NonNullable< EVENT_STORE['_types'] diff --git a/packages/json-schema-command/src/command.fixtures.test.ts b/packages/json-schema-command/src/command.fixtures.test.ts index d27e9b2b..7521832a 100644 --- a/packages/json-schema-command/src/command.fixtures.test.ts +++ b/packages/json-schema-command/src/command.fixtures.test.ts @@ -98,7 +98,7 @@ export const counterEventStore = new EventStore({ counterIncrementedEvent, counterDeletedEvent, ], - reduce: countersReducer, + reducer: countersReducer, eventStorageAdapter: eventStorageAdapterMock, }); diff --git a/packages/test-tools/src/mockedEventStore.ts b/packages/test-tools/src/mockedEventStore.ts index 303f1108..9b37a1d7 100644 --- a/packages/test-tools/src/mockedEventStore.ts +++ b/packages/test-tools/src/mockedEventStore.ts @@ -47,7 +47,7 @@ export class MockedEventStore< super({ eventStoreId: eventStore.eventStoreId, eventStoreEvents: eventStore.eventStoreEvents, - reduce: eventStore.reduce, + reducer: eventStore.reducer, simulateSideEffect: eventStore.simulateSideEffect, eventStorageAdapter: new InMemoryEventStorageAdapter({ initialEvents }), }); From 7f11b5b325c5886f361cfd41364e5ea5e3be27bc Mon Sep 17 00:00:00 2001 From: Thomas Aribart Date: Fri, 29 Sep 2023 18:04:53 +0200 Subject: [PATCH 4/5] rename EventStoreEventsTypes to EventStoreEventTypes and EventStoreEventsDetails to EventStoreEventDetails --- demo/blueprint/src/pokemons/mock.ts | 8 ++++---- demo/blueprint/src/trainers/mock.ts | 6 +++--- .../catchPokemon/catchPokemon.unit.test.ts | 19 +++++++++---------- docs/docs/2-event-sourcing/3-event-stores.md | 12 ++++++------ .../connectedEventStore/publishPushedEvent.ts | 4 ++-- .../src/eventStore/eventStore.type.test.ts | 6 +++--- packages/core/src/eventStore/generics.ts | 10 ++-------- packages/core/src/index.ts | 4 ++-- .../core/src/messaging/channel/generics.ts | 4 ++-- packages/core/src/messaging/generics.ts | 6 +++--- packages/dam/src/fixtures.test.ts | 12 ++++++------ packages/dam/src/utils/eventBook.ts | 6 +++--- .../src/message.ts | 6 +++--- .../src/hooks/useAggregate.ts | 6 +++--- .../src/hooks/useAggregateEvents.ts | 6 +++--- .../src/hooks/useExistingAggregate.ts | 6 +++--- .../redux-event-storage-adapter/src/types.ts | 4 ++-- packages/test-tools/src/mockEventStore.ts | 18 +++++++++--------- packages/test-tools/src/muteEventStore.ts | 4 ++-- 19 files changed, 70 insertions(+), 77 deletions(-) diff --git a/demo/blueprint/src/pokemons/mock.ts b/demo/blueprint/src/pokemons/mock.ts index e7b5fc1d..2d422fbf 100644 --- a/demo/blueprint/src/pokemons/mock.ts +++ b/demo/blueprint/src/pokemons/mock.ts @@ -1,10 +1,10 @@ -import { EventStoreEventsDetails } from '@castore/core'; +import { EventStoreEventDetails } from '@castore/core'; import { pokemonsEventStore } from './eventStore'; export const pikachuId = 'pikachu-id'; -export const pikachuAppearedEvent: EventStoreEventsDetails< +export const pikachuAppearedEvent: EventStoreEventDetails< typeof pokemonsEventStore > = { aggregateId: pikachuId, @@ -20,7 +20,7 @@ export const pikachuAppearedEvent: EventStoreEventsDetails< }, }; -export const pikachuCaughtEvent: EventStoreEventsDetails< +export const pikachuCaughtEvent: EventStoreEventDetails< typeof pokemonsEventStore > = { aggregateId: pikachuId, @@ -32,7 +32,7 @@ export const pikachuCaughtEvent: EventStoreEventsDetails< }, }; -export const pikachuLevelledUpEvent: EventStoreEventsDetails< +export const pikachuLevelledUpEvent: EventStoreEventDetails< typeof pokemonsEventStore > = { aggregateId: pikachuId, diff --git a/demo/blueprint/src/trainers/mock.ts b/demo/blueprint/src/trainers/mock.ts index 6d132656..a3fc082f 100644 --- a/demo/blueprint/src/trainers/mock.ts +++ b/demo/blueprint/src/trainers/mock.ts @@ -1,10 +1,10 @@ -import { EventStoreEventsDetails } from '@castore/core'; +import { EventStoreEventDetails } from '@castore/core'; import { trainersEventStore } from './eventStore'; export const ashId = 'ash-ketchum-id'; -export const ashPokemonGameStartedEvent: EventStoreEventsDetails< +export const ashPokemonGameStartedEvent: EventStoreEventDetails< typeof trainersEventStore > = { aggregateId: ashId, @@ -16,7 +16,7 @@ export const ashPokemonGameStartedEvent: EventStoreEventsDetails< }, }; -export const ashPokemonCaughtEvent: EventStoreEventsDetails< +export const ashPokemonCaughtEvent: EventStoreEventDetails< typeof trainersEventStore > = { aggregateId: ashId, diff --git a/demo/implementation/functions/catchPokemon/catchPokemon.unit.test.ts b/demo/implementation/functions/catchPokemon/catchPokemon.unit.test.ts index 9cf9a739..a25d4821 100644 --- a/demo/implementation/functions/catchPokemon/catchPokemon.unit.test.ts +++ b/demo/implementation/functions/catchPokemon/catchPokemon.unit.test.ts @@ -1,6 +1,6 @@ import MockDate from 'mockdate'; -import { EventStoreEventsDetails } from '@castore/core'; +import { EventStoreEventDetails } from '@castore/core'; import { catchPokemonCommand } from '@castore/demo-blueprint'; import { mockEventStore } from '@castore/test-tools'; @@ -8,7 +8,7 @@ import { pokemonsEventStore } from '~/libs/eventStores/pokemons'; import { trainersEventStore } from '~/libs/eventStores/trainers'; const pikachuId = 'pikachu1'; -const pikachuAppearedEvent: EventStoreEventsDetails = +const pikachuAppearedEvent: EventStoreEventDetails = { aggregateId: pikachuId, version: 1, @@ -19,14 +19,13 @@ const pikachuAppearedEvent: EventStoreEventsDetails = }; const ashId = 'ash'; -const ashGameStartedEvent: EventStoreEventsDetails = - { - aggregateId: ashId, - version: 1, - type: 'GAME_STARTED', - timestamp: '2021-01-01T00:00:00.000Z', - payload: { trainerName: 'Ash Ketchum' }, - }; +const ashGameStartedEvent: EventStoreEventDetails = { + aggregateId: ashId, + version: 1, + type: 'GAME_STARTED', + timestamp: '2021-01-01T00:00:00.000Z', + payload: { trainerName: 'Ash Ketchum' }, +}; describe('Commands - catchPokemon', () => { const pokemonsEventStoreMock = mockEventStore(pokemonsEventStore, [ diff --git a/docs/docs/2-event-sourcing/3-event-stores.md b/docs/docs/2-event-sourcing/3-event-stores.md index 61a6b0e6..b9d50a2d 100644 --- a/docs/docs/2-event-sourcing/3-event-stores.md +++ b/docs/docs/2-event-sourcing/3-event-stores.md @@ -287,21 +287,21 @@ type PokemonsEventStoreId = EventStoreId; // => 'POKEMONS' ``` -- `EventStoreEventsTypes`: Returns the `EventStore` list of events types +- `EventStoreEventTypes`: Returns the `EventStore` list of events types ```ts -import type { EventStoreEventsTypes } from '@castore/core'; +import type { EventStoreEventTypes } from '@castore/core'; -type PokemonEventTypes = EventStoreEventsTypes; +type PokemonEventTypes = EventStoreEventTypes; // => [typeof pokemonAppearedEventType, typeof pokemonCaughtEventType...] ``` -- `EventStoreEventsDetails`: Returns the union of all the `EventStore` possible events details +- `EventStoreEventDetails`: Returns the union of all the `EventStore` possible events details ```ts -import type { EventStoreEventsDetails } from '@castore/core'; +import type { EventStoreEventDetails } from '@castore/core'; -type PokemonEventDetails = EventStoreEventsDetails; +type PokemonEventDetails = EventStoreEventDetails; // => EventTypeDetail // | EventTypeDetail // | ... diff --git a/packages/core/src/connectedEventStore/publishPushedEvent.ts b/packages/core/src/connectedEventStore/publishPushedEvent.ts index 0c05f964..3e45c9d5 100644 --- a/packages/core/src/connectedEventStore/publishPushedEvent.ts +++ b/packages/core/src/connectedEventStore/publishPushedEvent.ts @@ -1,6 +1,6 @@ import type { EventStoreAggregate, - EventStoreEventsDetails, + EventStoreEventDetails, } from '~/eventStore/generics'; import { NotificationMessageChannel, @@ -14,7 +14,7 @@ export const publishPushedEvent = async < >( connectedEventStore: CONNECTED_EVENT_STORE, message: { - event: EventStoreEventsDetails; + event: EventStoreEventDetails; nextAggregate?: EventStoreAggregate; }, ): Promise => { diff --git a/packages/core/src/eventStore/eventStore.type.test.ts b/packages/core/src/eventStore/eventStore.type.test.ts index 01a1a3d4..387f7187 100644 --- a/packages/core/src/eventStore/eventStore.type.test.ts +++ b/packages/core/src/eventStore/eventStore.type.test.ts @@ -8,7 +8,7 @@ import type { EventsQueryOptions } from '~/eventStorageAdapter'; import { EventStore, EventStoreAggregate, - EventStoreEventsDetails, + EventStoreEventDetails, GetAggregateOptions, } from '~/eventStore'; @@ -39,13 +39,13 @@ assertEventStoreId; // --- EVENTS DETAILS --- const assertPokemonEventDetails: A.Equals< - EventStoreEventsDetails, + EventStoreEventDetails, PokemonEventDetails > = 1; assertPokemonEventDetails; const assertAnyEventsDetails: A.Equals< - EventStoreEventsDetails, + EventStoreEventDetails, EventDetail > = 1; assertAnyEventsDetails; diff --git a/packages/core/src/eventStore/generics.ts b/packages/core/src/eventStore/generics.ts index 45392b0f..2a908b9e 100644 --- a/packages/core/src/eventStore/generics.ts +++ b/packages/core/src/eventStore/generics.ts @@ -3,16 +3,10 @@ import { EventStore } from './eventStore'; export type EventStoreId = EVENT_STORE['eventStoreId']; -/** - * @debt v2 "rename as EventStoreEventTypes" - */ -export type EventStoreEventsTypes = +export type EventStoreEventTypes = EVENT_STORE['eventStoreEvents']; -/** - * @debt v2 "rename as EventStoreEventDetails" - */ -export type EventStoreEventsDetails = +export type EventStoreEventDetails = NonNullable['details']; export type EventStoreReducer = diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 2439ad24..d8986d2e 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -23,8 +23,8 @@ export type { GetAggregateOptions, SimulationOptions, EventStoreId, - EventStoreEventsTypes, - EventStoreEventsDetails, + EventStoreEventTypes, + EventStoreEventDetails, EventStoreReducer, EventStoreAggregate, Reducer, diff --git a/packages/core/src/messaging/channel/generics.ts b/packages/core/src/messaging/channel/generics.ts index 94af2725..4b065161 100644 --- a/packages/core/src/messaging/channel/generics.ts +++ b/packages/core/src/messaging/channel/generics.ts @@ -1,6 +1,6 @@ import type { EventStore, - EventStoreEventsTypes, + EventStoreEventTypes, EventStoreId, } from '~/eventStore'; @@ -57,7 +57,7 @@ export type MessageChannelSourceEventStoreIdTypes< | StateCarryingMessageChannel | NotificationMessageChannel, EVENT_STORE_ID extends MessageChannelSourceEventStoreIds = MessageChannelSourceEventStoreIds, -> = EventStoreEventsTypes< +> = EventStoreEventTypes< Extract< MessageChannelSourceEventStores, { eventStoreId: EVENT_STORE_ID } diff --git a/packages/core/src/messaging/generics.ts b/packages/core/src/messaging/generics.ts index fcd4bc84..f2410b28 100644 --- a/packages/core/src/messaging/generics.ts +++ b/packages/core/src/messaging/generics.ts @@ -1,7 +1,7 @@ import type { EventStore, EventStoreId, - EventStoreEventsDetails, + EventStoreEventDetails, EventStoreAggregate, } from '~/eventStore'; @@ -23,7 +23,7 @@ export type EventStoreNotificationMessage = ? EVENT_STORE extends EventStore ? NotificationMessage< EventStoreId, - EventStoreEventsDetails + EventStoreEventDetails > : never : never; @@ -33,7 +33,7 @@ export type EventStoreStateCarryingMessage = ? EVENT_STORE extends EventStore ? StateCarryingMessage< EventStoreId, - EventStoreEventsDetails, + EventStoreEventDetails, EventStoreAggregate > : never diff --git a/packages/dam/src/fixtures.test.ts b/packages/dam/src/fixtures.test.ts index 0fced58f..ba1c9930 100644 --- a/packages/dam/src/fixtures.test.ts +++ b/packages/dam/src/fixtures.test.ts @@ -1,4 +1,4 @@ -import type { EventStoreEventsDetails } from '@castore/core'; +import type { EventStoreEventDetails } from '@castore/core'; import { pokemonsEventStore, trainersEventStore, @@ -19,7 +19,7 @@ export const garyOakId = 'garyOak'; // POKEMON EVENTS -export const pikachuEvents: EventStoreEventsDetails< +export const pikachuEvents: EventStoreEventDetails< typeof pokemonsEventStore >[] = [ { @@ -45,7 +45,7 @@ export const pikachuEvents: EventStoreEventsDetails< }, ]; -export const charizardEvents: EventStoreEventsDetails< +export const charizardEvents: EventStoreEventDetails< typeof pokemonsEventStore >[] = [ { @@ -58,7 +58,7 @@ export const charizardEvents: EventStoreEventsDetails< }, ]; -export const arcanineEvents: EventStoreEventsDetails< +export const arcanineEvents: EventStoreEventDetails< typeof pokemonsEventStore >[] = [ { @@ -80,7 +80,7 @@ export const arcanineEvents: EventStoreEventsDetails< // TRAINER EVENTS -export const ashKetchumEvents: EventStoreEventsDetails< +export const ashKetchumEvents: EventStoreEventDetails< typeof trainersEventStore >[] = [ { @@ -99,7 +99,7 @@ export const ashKetchumEvents: EventStoreEventsDetails< }, ]; -export const garyOakEvents: EventStoreEventsDetails< +export const garyOakEvents: EventStoreEventDetails< typeof trainersEventStore >[] = [ { diff --git a/packages/dam/src/utils/eventBook.ts b/packages/dam/src/utils/eventBook.ts index f115446c..7de8dd34 100644 --- a/packages/dam/src/utils/eventBook.ts +++ b/packages/dam/src/utils/eventBook.ts @@ -1,7 +1,7 @@ import type { EventDetail, EventStore, - EventStoreEventsDetails, + EventStoreEventDetails, EventStoreNotificationMessage, } from '@castore/core'; @@ -26,7 +26,7 @@ export class EventBook { getBookedEvents = ( aggregateId: string, - ): EventStoreEventsDetails[] => + ): EventStoreEventDetails[] => this.eventsByAggregateId[aggregateId] ?? []; getMessagesToPour = ({ @@ -36,7 +36,7 @@ export class EventBook { areAllAggregatesScanned: boolean; fetchedEventsCursor: string; }): MessageBatch => { - const eventsToPour: EventStoreEventsDetails[] = []; + const eventsToPour: EventStoreEventDetails[] = []; for (const aggregateId in this.eventsByAggregateId) { const aggregateEvents = this.getBookedEvents(aggregateId); diff --git a/packages/event-bridge-message-bus-adapter/src/message.ts b/packages/event-bridge-message-bus-adapter/src/message.ts index 5360cb94..94c4c325 100644 --- a/packages/event-bridge-message-bus-adapter/src/message.ts +++ b/packages/event-bridge-message-bus-adapter/src/message.ts @@ -1,7 +1,7 @@ import type { EventBridgeEvent } from 'aws-lambda'; import type { - EventStoreEventsDetails, + EventStoreEventDetails, EventStoreAggregate, AggregateExistsMessage, AggregateExistsMessageBus, @@ -33,7 +33,7 @@ type EventBridgeStateCarryingMessageBusMessage< StateCarryingMessage< EVENT_STORE_ID, Extract< - EventStoreEventsDetails< + EventStoreEventDetails< Extract< MessageChannelSourceEventStores, { eventStoreId: EVENT_STORE_IDS } @@ -73,7 +73,7 @@ type EventBridgeNotificationMessageBusMessage< NotificationMessage< EVENT_STORE_ID, Extract< - EventStoreEventsDetails< + EventStoreEventDetails< Extract< MessageChannelSourceEventStores, { eventStoreId: EVENT_STORE_IDS } diff --git a/packages/redux-event-storage-adapter/src/hooks/useAggregate.ts b/packages/redux-event-storage-adapter/src/hooks/useAggregate.ts index 87843b15..095ba5c7 100644 --- a/packages/redux-event-storage-adapter/src/hooks/useAggregate.ts +++ b/packages/redux-event-storage-adapter/src/hooks/useAggregate.ts @@ -1,7 +1,7 @@ import { EventStore, EventStoreAggregate, - EventStoreEventsDetails, + EventStoreEventDetails, GetAggregateOptions, } from '@castore/core'; @@ -13,8 +13,8 @@ export const useAggregate = ( { maxVersion }: GetAggregateOptions = {}, ): { aggregate?: EventStoreAggregate; - events: EventStoreEventsDetails[]; - lastEvent?: EventStoreEventsDetails; + events: EventStoreEventDetails[]; + lastEvent?: EventStoreEventDetails; } => { const { events } = useAggregateEvents(eventStore, aggregateId, { maxVersion, diff --git a/packages/redux-event-storage-adapter/src/hooks/useAggregateEvents.ts b/packages/redux-event-storage-adapter/src/hooks/useAggregateEvents.ts index ca84c68c..ed938c61 100644 --- a/packages/redux-event-storage-adapter/src/hooks/useAggregateEvents.ts +++ b/packages/redux-event-storage-adapter/src/hooks/useAggregateEvents.ts @@ -3,7 +3,7 @@ import { useSelector } from 'react-redux'; import { EventsQueryOptions, EventStore, - EventStoreEventsDetails, + EventStoreEventDetails, } from '@castore/core'; import { ReduxEventStorageAdapter } from '~/adapter'; @@ -15,7 +15,7 @@ export const useAggregateEvents = ( eventStore: EVENT_STORE, aggregateId: string, { minVersion, maxVersion, reverse, limit }: EventsQueryOptions = {}, -): { events: EventStoreEventsDetails[] } => { +): { events: EventStoreEventDetails[] } => { let events = (useSelector(state => { const eventStorageAdapter = eventStore.getEventStorageAdapter(); @@ -33,7 +33,7 @@ export const useAggregateEvents = ( } return eventStoreState.eventsByAggregateId[aggregateId]; - }) ?? []) as EventStoreEventsDetails[]; + }) ?? []) as EventStoreEventDetails[]; if (minVersion !== undefined) { events = events.filter(({ version }) => version >= minVersion); diff --git a/packages/redux-event-storage-adapter/src/hooks/useExistingAggregate.ts b/packages/redux-event-storage-adapter/src/hooks/useExistingAggregate.ts index 12248cbb..fcbb15bf 100644 --- a/packages/redux-event-storage-adapter/src/hooks/useExistingAggregate.ts +++ b/packages/redux-event-storage-adapter/src/hooks/useExistingAggregate.ts @@ -1,7 +1,7 @@ import { EventStore, EventStoreAggregate, - EventStoreEventsDetails, + EventStoreEventDetails, GetAggregateOptions, AggregateNotFoundError, } from '@castore/core'; @@ -14,8 +14,8 @@ export const useExistingAggregate = ( options: GetAggregateOptions = {}, ): { aggregate: EventStoreAggregate; - events: EventStoreEventsDetails[]; - lastEvent: EventStoreEventsDetails; + events: EventStoreEventDetails[]; + lastEvent: EventStoreEventDetails; } => { const { aggregate, events, lastEvent } = useAggregate( eventStore, diff --git a/packages/redux-event-storage-adapter/src/types.ts b/packages/redux-event-storage-adapter/src/types.ts index d7857685..d2dd51c9 100644 --- a/packages/redux-event-storage-adapter/src/types.ts +++ b/packages/redux-event-storage-adapter/src/types.ts @@ -2,13 +2,13 @@ import { Reducer } from '@reduxjs/toolkit'; import { EventStore, - EventStoreEventsDetails, + EventStoreEventDetails, EventStoreId, } from '@castore/core'; export type EventStoreReduxState = { - eventsByAggregateId: Record[]>; + eventsByAggregateId: Record[]>; aggregateIds: { aggregateId: string; initialEventTimestamp: string; diff --git a/packages/test-tools/src/mockEventStore.ts b/packages/test-tools/src/mockEventStore.ts index 586b54fb..24199695 100644 --- a/packages/test-tools/src/mockEventStore.ts +++ b/packages/test-tools/src/mockEventStore.ts @@ -1,8 +1,8 @@ import { EventStore, EventStoreId, - EventStoreEventsTypes, - EventStoreEventsDetails, + EventStoreEventTypes, + EventStoreEventDetails, EventStoreReducer, EventStoreAggregate, } from '@castore/core'; @@ -11,20 +11,20 @@ import { MockedEventStore } from './mockedEventStore'; export const mockEventStore = ( eventStore: EVENT_STORE, - initialEvents: EventStoreEventsDetails[] = [], + initialEvents: EventStoreEventDetails[] = [], ): MockedEventStore< EventStoreId, - EventStoreEventsTypes, - EventStoreEventsDetails, - EventStoreEventsDetails, + EventStoreEventTypes, + EventStoreEventDetails, + EventStoreEventDetails, EventStoreReducer, EventStoreAggregate > => new MockedEventStore< EventStoreId, - EventStoreEventsTypes, - EventStoreEventsDetails, - EventStoreEventsDetails, + EventStoreEventTypes, + EventStoreEventDetails, + EventStoreEventDetails, EventStoreReducer, EventStoreAggregate >({ eventStore, initialEvents }); diff --git a/packages/test-tools/src/muteEventStore.ts b/packages/test-tools/src/muteEventStore.ts index 20df583c..1ac46c5a 100644 --- a/packages/test-tools/src/muteEventStore.ts +++ b/packages/test-tools/src/muteEventStore.ts @@ -1,9 +1,9 @@ -import { EventStore, EventStoreEventsDetails } from '@castore/core'; +import { EventStore, EventStoreEventDetails } from '@castore/core'; import { InMemoryEventStorageAdapter } from '@castore/inmemory-event-storage-adapter'; export const muteEventStore = ( eventStore: EVENT_STORE, - initialEvents: EventStoreEventsDetails[] = [], + initialEvents: EventStoreEventDetails[] = [], ): void => { eventStore.eventStorageAdapter = new InMemoryEventStorageAdapter({ initialEvents, From 775ebd19379dd7a91912f77db9ceb0b52f6c9b82 Mon Sep 17 00:00:00 2001 From: Thomas Aribart Date: Fri, 29 Sep 2023 18:09:12 +0200 Subject: [PATCH 5/5] rename eventStoreEvents to eventTypes --- demo/blueprint/src/pokemons/eventStore.ts | 2 +- demo/blueprint/src/trainers/eventStore.ts | 2 +- docs/docs/2-event-sourcing/3-event-stores.md | 8 ++++---- packages/core/src/command/command.fixtures.test.ts | 2 +- .../src/connectedEventStore/connectedEventStore.ts | 4 ++-- .../src/eventStore/eventStore.fixtures.test.ts | 6 +----- packages/core/src/eventStore/eventStore.ts | 14 ++++---------- .../core/src/eventStore/eventStore.unit.test.ts | 4 ++-- packages/core/src/eventStore/generics.ts | 2 +- .../src/command.fixtures.test.ts | 2 +- packages/test-tools/src/mockedEventStore.ts | 2 +- 11 files changed, 19 insertions(+), 29 deletions(-) diff --git a/demo/blueprint/src/pokemons/eventStore.ts b/demo/blueprint/src/pokemons/eventStore.ts index 954a5c77..3a5f0d9e 100644 --- a/demo/blueprint/src/pokemons/eventStore.ts +++ b/demo/blueprint/src/pokemons/eventStore.ts @@ -5,7 +5,7 @@ import { appearedEvent, caughtByTrainerEvent, levelledUpEvent } from './events'; export const pokemonsEventStore = new EventStore({ eventStoreId: 'POKEMONS', - eventStoreEvents: [appearedEvent, caughtByTrainerEvent, levelledUpEvent], + eventTypes: [appearedEvent, caughtByTrainerEvent, levelledUpEvent], reducer: (pokemonAggregate: PokemonAggregate, event): PokemonAggregate => { const { version, aggregateId } = event; diff --git a/demo/blueprint/src/trainers/eventStore.ts b/demo/blueprint/src/trainers/eventStore.ts index a99d64ed..e3356a1d 100644 --- a/demo/blueprint/src/trainers/eventStore.ts +++ b/demo/blueprint/src/trainers/eventStore.ts @@ -5,7 +5,7 @@ import { gameStartedEvent, pokemonCaughtEvent } from './events'; export const trainersEventStore = new EventStore({ eventStoreId: 'TRAINERS', - eventStoreEvents: [gameStartedEvent, pokemonCaughtEvent], + eventTypes: [gameStartedEvent, pokemonCaughtEvent], reducer: (trainerAggregate: TrainerAggregate, event): TrainerAggregate => { const { version, aggregateId } = event; diff --git a/docs/docs/2-event-sourcing/3-event-stores.md b/docs/docs/2-event-sourcing/3-event-stores.md index b9d50a2d..45a75409 100644 --- a/docs/docs/2-event-sourcing/3-event-stores.md +++ b/docs/docs/2-event-sourcing/3-event-stores.md @@ -26,7 +26,7 @@ import { EventStore } from '@castore/core'; const pokemonsEventStore = new EventStore({ eventStoreId: 'POKEMONS', - eventStoreEvents: [ + eventTypes: [ pokemonAppearedEventType, pokemonCaughtEventType, pokemonLeveledUpEventType, @@ -51,7 +51,7 @@ const pokemonsEventStore = new EventStore({ **Constructor:** - eventStoreId (string): A string identifying the event store -- eventStoreEvents (EventType[]): The list of event types in the event store +- eventTypes (EventType[]): The list of event types in the event store - reduce (EventType[]): A reducer function that can be applied to the store event types - onEventPushed (?(pushEventResponse: PushEventResponse) => Promise<void>): To run a callback after events are pushed (input is exactly the return value of the pushEvent method) - eventStorageAdapter (?EventStorageAdapter): See fetching events @@ -69,10 +69,10 @@ const pokemonsEventStoreId = pokemonsEventStore.eventStoreId; // => 'POKEMONS' ``` -- eventStoreEvents (EventType[]) +- eventTypes (EventType[]) ```ts -const pokemonsEventStoreEvents = pokemonsEventStore.eventStoreEvents; +const pokemonsEventTypes = pokemonsEventStore.eventTypes; // => [pokemonAppearedEventType, pokemonCaughtEventType...] ``` diff --git a/packages/core/src/command/command.fixtures.test.ts b/packages/core/src/command/command.fixtures.test.ts index e4c8d052..9695881d 100644 --- a/packages/core/src/command/command.fixtures.test.ts +++ b/packages/core/src/command/command.fixtures.test.ts @@ -110,7 +110,7 @@ export const countersReducer = ( export const counterEventStore = new EventStore({ eventStoreId: 'Counters', - eventStoreEvents: [ + eventTypes: [ counterCreatedEvent, counterIncrementedEvent, counterDeletedEvent, diff --git a/packages/core/src/connectedEventStore/connectedEventStore.ts b/packages/core/src/connectedEventStore/connectedEventStore.ts index 0e408c78..51950882 100644 --- a/packages/core/src/connectedEventStore/connectedEventStore.ts +++ b/packages/core/src/connectedEventStore/connectedEventStore.ts @@ -73,7 +73,7 @@ export class ConnectedEventStore< aggregate: AGGREGATE; }; eventStoreId: EVENT_STORE_ID; - eventStoreEvents: EVENT_TYPES; + eventTypes: EVENT_TYPES; reducer: REDUCER; simulateSideEffect: SideEffectsSimulator; getEvents: EventsGetter; @@ -113,7 +113,7 @@ export class ConnectedEventStore< messageChannel: MESSAGE_CHANNEL, ) { this.eventStoreId = eventStore.eventStoreId; - this.eventStoreEvents = eventStore.eventStoreEvents; + this.eventTypes = eventStore.eventTypes; this.reducer = eventStore.reducer; this.simulateSideEffect = eventStore.simulateSideEffect; this.getEvents = eventStore.getEvents; diff --git a/packages/core/src/eventStore/eventStore.fixtures.test.ts b/packages/core/src/eventStore/eventStore.fixtures.test.ts index 41f61103..833bbb0f 100644 --- a/packages/core/src/eventStore/eventStore.fixtures.test.ts +++ b/packages/core/src/eventStore/eventStore.fixtures.test.ts @@ -114,11 +114,7 @@ export const pokemonsReducer = ( export const pokemonsEventStore = new EventStore({ eventStoreId: 'POKEMONS', - eventStoreEvents: [ - pokemonAppearedEvent, - pokemonCaughtEvent, - pokemonLeveledUpEvent, - ], + eventTypes: [pokemonAppearedEvent, pokemonCaughtEvent, pokemonLeveledUpEvent], reducer: pokemonsReducer, eventStorageAdapter: eventStorageAdapterMock, }); diff --git a/packages/core/src/eventStore/eventStore.ts b/packages/core/src/eventStore/eventStore.ts index 5d3b199e..3f4db110 100644 --- a/packages/core/src/eventStore/eventStore.ts +++ b/packages/core/src/eventStore/eventStore.ts @@ -90,10 +90,7 @@ export class EventStore< aggregate: AGGREGATE; }; eventStoreId: EVENT_STORE_ID; - /** - * @debt v2 "rename as eventTypes" - */ - eventStoreEvents: EVENT_TYPES; + eventTypes: EVENT_TYPES; reducer: REDUCER; simulateSideEffect: SideEffectsSimulator; @@ -121,7 +118,7 @@ export class EventStore< constructor({ eventStoreId, - eventStoreEvents, + eventTypes, reducer, simulateSideEffect = (indexedEvents, event) => ({ ...indexedEvents, @@ -130,16 +127,13 @@ export class EventStore< eventStorageAdapter: $eventStorageAdapter, }: { eventStoreId: EVENT_STORE_ID; - /** - * @debt v2 "rename as eventTypes" - */ - eventStoreEvents: EVENT_TYPES; + eventTypes: EVENT_TYPES; reducer: REDUCER; simulateSideEffect?: SideEffectsSimulator; eventStorageAdapter?: EventStorageAdapter; }) { this.eventStoreId = eventStoreId; - this.eventStoreEvents = eventStoreEvents; + this.eventTypes = eventTypes; this.reducer = reducer; this.simulateSideEffect = simulateSideEffect; this.eventStorageAdapter = $eventStorageAdapter; diff --git a/packages/core/src/eventStore/eventStore.unit.test.ts b/packages/core/src/eventStore/eventStore.unit.test.ts index 9c18d87e..02fc9df5 100644 --- a/packages/core/src/eventStore/eventStore.unit.test.ts +++ b/packages/core/src/eventStore/eventStore.unit.test.ts @@ -42,7 +42,7 @@ describe('event store', () => { expect(new Set(Object.keys(pokemonsEventStore))).toStrictEqual( new Set([ 'eventStoreId', - 'eventStoreEvents', + 'eventTypes', 'reducer', 'simulateSideEffect', 'eventStorageAdapter', @@ -60,7 +60,7 @@ describe('event store', () => { expect(pokemonsEventStore.eventStoreId).toBe('POKEMONS'); - expect(pokemonsEventStore.eventStoreEvents).toStrictEqual([ + expect(pokemonsEventStore.eventTypes).toStrictEqual([ pokemonAppearedEvent, pokemonCaughtEvent, pokemonLeveledUpEvent, diff --git a/packages/core/src/eventStore/generics.ts b/packages/core/src/eventStore/generics.ts index 2a908b9e..740ff570 100644 --- a/packages/core/src/eventStore/generics.ts +++ b/packages/core/src/eventStore/generics.ts @@ -4,7 +4,7 @@ export type EventStoreId = EVENT_STORE['eventStoreId']; export type EventStoreEventTypes = - EVENT_STORE['eventStoreEvents']; + EVENT_STORE['eventTypes']; export type EventStoreEventDetails = NonNullable['details']; diff --git a/packages/json-schema-command/src/command.fixtures.test.ts b/packages/json-schema-command/src/command.fixtures.test.ts index 7521832a..8177a37f 100644 --- a/packages/json-schema-command/src/command.fixtures.test.ts +++ b/packages/json-schema-command/src/command.fixtures.test.ts @@ -93,7 +93,7 @@ export const countersReducer = ( export const counterEventStore = new EventStore({ eventStoreId: 'Counters', - eventStoreEvents: [ + eventTypes: [ counterCreatedEvent, counterIncrementedEvent, counterDeletedEvent, diff --git a/packages/test-tools/src/mockedEventStore.ts b/packages/test-tools/src/mockedEventStore.ts index 9b37a1d7..f2acb265 100644 --- a/packages/test-tools/src/mockedEventStore.ts +++ b/packages/test-tools/src/mockedEventStore.ts @@ -46,7 +46,7 @@ export class MockedEventStore< }) { super({ eventStoreId: eventStore.eventStoreId, - eventStoreEvents: eventStore.eventStoreEvents, + eventTypes: eventStore.eventTypes, reducer: eventStore.reducer, simulateSideEffect: eventStore.simulateSideEffect, eventStorageAdapter: new InMemoryEventStorageAdapter({ initialEvents }),