diff --git a/docs/docs/1-introduction.md b/docs/docs/1-introduction.md
index be0c9eef..f7f2de50 100644
--- a/docs/docs/1-introduction.md
+++ b/docs/docs/1-introduction.md
@@ -22,9 +22,9 @@ After years of using it at [Theodo](https://dev.to/slsbytheodo), we have grown t
With Castore, you'll be able to:
-- Define your [event stores](/docs/the-basics#eventstore)
-- Fetch and push new [events](/docs/the-basics#events) seamlessly
-- Implement and test your [commands](/docs/the-basics#command)
+- Define your [event stores](./3-event-sourcing/3-event-stores.md)
+- Fetch and push new [events](./3-event-sourcing/1-events.md) seamlessly
+- Implement and test your [commands](./3-event-sourcing/5-pushing-events.md)
- ...and much more!
All that with first-class developer experience and minimal boilerplate ✨
diff --git a/docs/docs/3-event-sourcing/1-events.md b/docs/docs/3-event-sourcing/1-events.md
index 894b7ea2..26181e3b 100644
--- a/docs/docs/3-event-sourcing/1-events.md
+++ b/docs/docs/3-event-sourcing/1-events.md
@@ -53,7 +53,7 @@ const pokemonAppearedEventType = new EventType<
:::info
-Note that we only provided TS types for `payload` and `metadata` properties. That is because, as stated in the [core design](/docs/introduction#-core-design), **Castore is meant to be as flexible as possible**, and that includes the validation library you want to use (if any): The `EventType` class can be used directly if no validation is required, or implemented by [other classes](../5-resources.md) which will add run-time validation methods to it 👍
+Note that we only provided TS types for `payload` and `metadata` properties. That is because, as stated in the [core design](../1-introduction.md#-core-design), **Castore is meant to be as flexible as possible**, and that includes the validation library you want to use (if any): The `EventType` class can be used directly if no validation is required, or implemented by [other classes](../5-packages.md#-event-types) which will add run-time validation methods to it 👍
:::
diff --git a/docs/docs/3-event-sourcing/3-event-stores.md b/docs/docs/3-event-sourcing/3-event-stores.md
index 36246e0a..591493ad 100644
--- a/docs/docs/3-event-sourcing/3-event-stores.md
+++ b/docs/docs/3-event-sourcing/3-event-stores.md
@@ -4,7 +4,7 @@ sidebar_position: 3
# 📙 Event Store
-Once you've defined your [event types](#eventtype) and how to [aggregate](#reducer) them, you can bundle them together in an `EventStore` class. Each event store in your application represents a business entity.
+Once you've defined your [event types](./1-events.md) and how to [aggregate](./2-aggregates-reducers.md) them, you can bundle them together in an `EventStore` class. Each event store in your application represents a business entity.
:::note
@@ -14,7 +14,7 @@ Think of event stores as _"what tables would be in CRUD"_, except that instead o
![Event Store](../../assets/docSchemas/eventStore.png)
-In Castore, `EventStore` classes are NOT responsible for actually storing data (this will come with [event storage adapters](#eventstorageadapter)). But rather to provide a boilerplate-free and type-safe interface to perform many actions such as:
+In Castore, `EventStore` classes are NOT responsible for actually storing data (this will come with [event storage adapters](./4-fetching-events.md)). But rather to provide a boilerplate-free and type-safe interface to perform many actions such as:
- Listing aggregate ids
- Accessing events of an aggregate
@@ -39,7 +39,7 @@ const pokemonsEventStore = new EventStore({
:::info
-> ☝️ The `EventStore` class is the heart of Castore, it even gave it its name!
+☝️ The `EventStore` class is the heart of Castore, it even gave it its name!
:::
@@ -51,9 +51,9 @@ const pokemonsEventStore = new EventStore({
>
> - eventStoreId (string)
: A string identifying the event store
> - 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
+> - 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 EventStorageAdapter
+> - storageAdapter (?EventStorageAdapter)
: See EventStorageAdapter
>
> ☝️ The return type of the `reducer` is used to infer the `Aggregate` type of the `EventStore`, so it is important to type it explicitely.
>
@@ -87,7 +87,7 @@ const pokemonsEventStore = new EventStore({
> // => undefined (we did not provide one in this example)
> ```
>
-> - storageAdapter ?EventStorageAdapter
: See EventStorageAdapter
+> - storageAdapter ?EventStorageAdapter
: See EventStorageAdapter
>
> ```ts
> const storageAdapter = pokemonsEventStore.storageAdapter;
@@ -115,11 +115,11 @@ const pokemonsEventStore = new EventStore({
> const myPikachuAggregate = pokemonsEventStore.buildAggregate(myPikachuEvents);
> ```
>
-> - groupEvent ((eventDetail: EventDetail, opt?: OptionsObj = {}) => GroupedEvent)
: See Event Groups.
+> - groupEvent ((eventDetail: EventDetail, opt?: OptionsObj = {}) => GroupedEvent)
: See Event Groups.
>
> **Async Methods:**
>
-> The following methods interact with the data layer of your event store through its [`EventStorageAdapter`](#eventstorageadapter). 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 `UndefinedStorageAdapterError` 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
.
>
@@ -208,13 +208,13 @@ const pokemonsEventStore = new EventStore({
>
> `OptionsObj` contains the following properties:
>
-> - prevAggregate (?Aggregate)
: The aggregate at the current version, i.e. before having pushed the event. Can be useful in some cases like when using the ConnectedEventStore class
+> - prevAggregate (?Aggregate)
: The aggregate at the current version, i.e. before having pushed the event. Can be useful in some cases like when using the ConnectedEventStore class
> - force (?boolean)
: To force push the event even if one already exists for the corresponding aggregateId
and version
. Any existing event will be overridden, so use with extra care, mainly in data migrations.
>
> `ResponseObj` contains the following properties:
>
> - event (EventDetail)
: The complete event (includes the timestamp
)
-> - nextAggregate (?Aggregate)
: The aggregate at the new version, i.e. after having pushed the event. Returned only if the event is an initial event, if the prevAggregate
option was provided, or when using a ConnectedEventStore class connected to a state-carrying message bus or queue
+> - nextAggregate (?Aggregate)
: The aggregate at the new version, i.e. after having pushed the event. Returned only if the event is an initial event, if the prevAggregate
option was provided, or when using a ConnectedEventStore class connected to a state-carrying message bus or queue
>
> ```ts
> const { event: completeEvent, nextAggregate } =
diff --git a/docs/docs/3-event-sourcing/4-fetching-events.md b/docs/docs/3-event-sourcing/4-fetching-events.md
index ed67982f..c2eb3716 100644
--- a/docs/docs/3-event-sourcing/4-fetching-events.md
+++ b/docs/docs/3-event-sourcing/4-fetching-events.md
@@ -24,11 +24,12 @@ const pokemonsEventStore = new EventStore({
pokemonsEventStore.storageAdapter = mySuperStorageAdapter;
const { events } = await pokemonsEventStore.getEvents('pikachu1');
+const { aggregate } = await pokemonsEventStore.getAggregate('pikachu1');
// 🙌 Will work!
```
:::info
-You can choose to build an event storage adapter that suits your usage. However, we highly recommend using an [off-the-shelf adapter](../5-resources.md) (if the storage solution that you use does not have an adapter yet, feel free to create/upvote an issue, or contribute 🤗).
+You can choose to build an event storage adapter that suits your usage. However, we highly recommend using an [off-the-shelf adapter](../5-packages.md#-event-storage-adapters) (if the storage solution that you use does not have an adapter yet, feel free to create/upvote an issue, or contribute 🤗).
:::
diff --git a/docs/docs/3-event-sourcing/5-pushing-events.md b/docs/docs/3-event-sourcing/5-pushing-events.md
index 8c044f0e..d46fd99a 100644
--- a/docs/docs/3-event-sourcing/5-pushing-events.md
+++ b/docs/docs/3-event-sourcing/5-pushing-events.md
@@ -47,11 +47,11 @@ const catchPokemonCommand = new Command({
:::info
-Note that we only provided TS types for `Input` and `Output` properties. That is because, as stated in the [core design](/docs/introduction#-core-design), **Castore is meant to be as flexible as possible**, and that includes the validation library you want to use (if any): The `Command` class can be used directly if no validation is required, or implemented by [other classes](../5-resources.md) which will add run-time validation methods to it 👍
+Note that we only provided TS types for `Input` and `Output` properties. That is because, as stated in the [core design](../1-introduction.md#-core-design), **Castore is meant to be as flexible as possible**, and that includes the validation library you want to use (if any): The `Command` class can be used directly if no validation is required, or implemented by [other classes](../5-packages.md#-commands) which will add run-time validation methods to it 👍
:::
-`Commands` handlers should NOT use [read models](/docs/advanced-usage#read-models) when validating that a modification is acceptable. Read models are like cache: They are not the source of truth, and may not represent the freshest state.
+`Commands` handlers should NOT use [read models](../4-reacting-to-events/6-read-models.md) when validating that a modification is acceptable. Read models are like cache: They are not the source of truth, and may not represent the freshest state.
Fetching and pushing events non-simultaneously exposes your application to [race conditions](https://en.wikipedia.org/wiki/Race_condition). To counter that, commands are designed to be retried when an `EventAlreadyExistsError` is triggered (which is part of the `EventStorageAdapter` interface).
diff --git a/docs/docs/4-reacting-to-events/1-messages.md b/docs/docs/4-reacting-to-events/1-messages.md
index 495c183f..bc9668d2 100644
--- a/docs/docs/4-reacting-to-events/1-messages.md
+++ b/docs/docs/4-reacting-to-events/1-messages.md
@@ -87,4 +87,4 @@ type PokemonEventStateCarryingMessage = EventStoreStateCarryingMessage<
>;
```
-All types of message can be published through message channels, i.e. [Message Queues](#messagequeue) or [Message Buses](#messagebus).
+All types of message can be published through message channels, i.e. [Message Queues](./2-message-queues.md) or [Message Buses](./3-message-buses.md).
diff --git a/docs/docs/4-reacting-to-events/2-message-queues.md b/docs/docs/4-reacting-to-events/2-message-queues.md
index 42cfbcd8..f28e3962 100644
--- a/docs/docs/4-reacting-to-events/2-message-queues.md
+++ b/docs/docs/4-reacting-to-events/2-message-queues.md
@@ -53,7 +53,7 @@ await messageQueue.publishMessage(...);
:::info
-You can code your own `MessageQueueAdapter` (simply implement the `MessageChannelAdapter` interface), but we highly recommend using an [off-the-shelf adapter](../5-resources.md) (if the messaging solution that you use does not have an adapter yet, feel free to create/upvote an issue, or contribute 🤗).
+You can code your own `MessageQueueAdapter` (simply implement the `MessageChannelAdapter` interface), but we highly recommend using an [off-the-shelf adapter](../5-packages.md#-message-queue-adapters) (if the messaging solution that you use does not have an adapter yet, feel free to create/upvote an issue, or contribute 🤗).
:::
@@ -82,7 +82,7 @@ const appMessagesWorker = async ({ Records }: SQSMessageQueueMessage) => {
>
> - messageQueueId (string)
: A string identifying the message queue
> - sourceEventStores (EventStore[])
: List of event stores that the message queue will broadcast events from
-> - messageQueueAdapter (?MessageChannelAdapter)
: See section on MessageQueueAdapters
+> - messageQueueAdapter (?MessageChannelAdapter)
: Message queue adapter
>
> **Properties:**
>
@@ -100,7 +100,7 @@ const appMessagesWorker = async ({ Records }: SQSMessageQueueMessage) => {
> // => [pokemonsEventStore, trainersEventStore...]
> ```
>
-> - messageChannelAdapter ?MessageChannelAdapter
: See section on MessageQueueAdapters
+> - messageChannelAdapter ?MessageChannelAdapter
: Returns the associated message queue adapter (potentially undefined)
>
> ```ts
> const appMessageQueueAdapter = appMessageQueue.messageChannelAdapter;
diff --git a/docs/docs/4-reacting-to-events/3-message-buses.md b/docs/docs/4-reacting-to-events/3-message-buses.md
index 6bfcfb88..7ef17da3 100644
--- a/docs/docs/4-reacting-to-events/3-message-buses.md
+++ b/docs/docs/4-reacting-to-events/3-message-buses.md
@@ -53,7 +53,7 @@ await messageBus.publishMessage(...);
:::info
-You can code your own `MessageBusAdapter` (simply implement the `MessageChannelAdapter` interface), but we highly recommend using an [off-the-shelf adapter](../5-resources.md) (if the messaging solution that you use is missing, feel free to create/upvote an issue, or contribute 🤗).
+You can code your own `MessageBusAdapter` (simply implement the `MessageChannelAdapter` interface), but we highly recommend using an [off-the-shelf adapter](../5-packages.md#-message-buses-adapters) (if the messaging solution that you use is missing, feel free to create/upvote an issue, or contribute 🤗).
:::
@@ -82,7 +82,7 @@ const pokemonMessagesListener = async (
>
> - messageBusId (string)
: A string identifying the message bus
> - sourceEventStores (EventStore[])
: List of event stores that the message bus will broadcast events from
-> - messageBusAdapter (?MessageChannelAdapter)
: See section on MessageBusAdapters
+> - messageBusAdapter (?MessageChannelAdapter)
: Message bus adapter
>
> **Properties:**
>
@@ -100,7 +100,7 @@ const pokemonMessagesListener = async (
> // => [pokemonsEventStore, trainersEventStore...]
> ```
>
-> - messageChannelAdapter ?MessageChannelAdapter
: See section on MessageBusAdapters
+> - messageChannelAdapter ?MessageChannelAdapter
: Returns the associated message bus adapter (potentially undefined)
>
> ```ts
> const appMessageBusAdapter = appMessageBus.messageChannelAdapter;