Skip to content

Commit

Permalink
Merge pull request #149 from castore-dev/rework-documentation-3
Browse files Browse the repository at this point in the history
fix: broken links
  • Loading branch information
ThomasAribart committed Sep 8, 2023
2 parents 22cc373 + e76b81c commit f99e47c
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 24 deletions.
6 changes: 3 additions & 3 deletions docs/docs/1-introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 ✨
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/3-event-sourcing/1-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 👍

:::

Expand Down
20 changes: 10 additions & 10 deletions docs/docs/3-event-sourcing/3-event-stores.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand All @@ -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!

:::

Expand All @@ -51,9 +51,9 @@ const pokemonsEventStore = new EventStore({
>
> - <code>eventStoreId <i>(string)</i></code>: A string identifying the event store
> - <code>eventStoreEvents <i>(EventType[])</i></code>: The list of event types in the event store
> - <code>reduce <i>(EventType[])</i></code>: A <a href="#reducer">reducer function</a> that can be applied to the store event types
> - <code>reduce <i>(EventType[])</i></code>: A <a href="../aggregates-reducers">reducer function</a> that can be applied to the store event types
> - <code>onEventPushed <i>?(pushEventResponse: PushEventResponse => Promise(void))</i></code>: To run a callback after events are pushed (input is exactly the return value of the <code>pushEvent</code> method)
> - <code>storageAdapter <i>(?EventStorageAdapter)</i></code>: See <a href="#eventstorageadapter">EventStorageAdapter</a>
> - <code>storageAdapter <i>(?EventStorageAdapter)</i></code>: See <a href="../fetching-events">EventStorageAdapter</a>
>
> ☝️ The return type of the `reducer` is used to infer the `Aggregate` type of the `EventStore`, so it is important to type it explicitely.
>
Expand Down Expand Up @@ -87,7 +87,7 @@ const pokemonsEventStore = new EventStore({
> // => undefined (we did not provide one in this example)
> ```
>
> - <code>storageAdapter <i>?EventStorageAdapter</i></code>: See <a href="#eventstorageadapter">EventStorageAdapter</a>
> - <code>storageAdapter <i>?EventStorageAdapter</i></code>: See <a href="../fetching-events">EventStorageAdapter</a>
>
> ```ts
> const storageAdapter = pokemonsEventStore.storageAdapter;
Expand Down Expand Up @@ -115,11 +115,11 @@ const pokemonsEventStore = new EventStore({
> const myPikachuAggregate = pokemonsEventStore.buildAggregate(myPikachuEvents);
> ```
>
> - <code>groupEvent <i>((eventDetail: EventDetail, opt?: OptionsObj = {}) => GroupedEvent)</i></code>: See <a href="#event-groups">Event Groups</a>.
> - <code>groupEvent <i>((eventDetail: EventDetail, opt?: OptionsObj = {}) => GroupedEvent)</i></code>: See <a href="../joining-data">Event Groups</a>.
>
> **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.
>
> - <code>getEvents <i>((aggregateId: string, opt?: OptionsObj = {}) => Promise(ResponseObj))</i></code>: Retrieves the events of an aggregate, ordered by <code>version</code>. Returns an empty array if no event is found for this <code>aggregateId</code>.
>
Expand Down Expand Up @@ -208,13 +208,13 @@ const pokemonsEventStore = new EventStore({
>
> `OptionsObj` contains the following properties:
>
> - <code>prevAggregate <i>(?Aggregate)</i></code>: The aggregate at the current version, i.e. before having pushed the event. Can be useful in some cases like when using the <a href="/docs/advanced-usage#connectedeventstore">ConnectedEventStore class</a>
> - <code>prevAggregate <i>(?Aggregate)</i></code>: The aggregate at the current version, i.e. before having pushed the event. Can be useful in some cases like when using the <a href="../../reacting-to-events/connected-event-store">ConnectedEventStore class</a>
> - <code>force <i>(?boolean)</i></code>: To force push the event even if one already exists for the corresponding <code>aggregateId</code> and <code>version</code>. Any existing event will be overridden, so use with extra care, mainly in <a href="https://www.npmjs.com/package/@castore/dam">data migrations</a>.
>
> `ResponseObj` contains the following properties:
>
> - <code>event <i>(EventDetail)</i></code>: The complete event (includes the <code>timestamp</code>)
> - <code>nextAggregate <i>(?Aggregate)</i></code>: The aggregate at the new version, i.e. after having pushed the event. Returned only if the event is an initial event, if the <code>prevAggregate</code> option was provided, or when using a <a href="/docs/advanced-usage#connectedeventstore">ConnectedEventStore class</a> connected to a <a href="/docs/advanced-usage#event-driven-architecture">state-carrying message bus or queue</a>
> - <code>nextAggregate <i>(?Aggregate)</i></code>: The aggregate at the new version, i.e. after having pushed the event. Returned only if the event is an initial event, if the <code>prevAggregate</code> option was provided, or when using a <a href="../../reacting-to-events/connected-event-store">ConnectedEventStore class</a> connected to a <a href="../../reacting-to-events/messages">state-carrying message bus or queue</a>
>
> ```ts
> const { event: completeEvent, nextAggregate } =
Expand Down
3 changes: 2 additions & 1 deletion docs/docs/3-event-sourcing/4-fetching-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 🤗).

:::
4 changes: 2 additions & 2 deletions docs/docs/3-event-sourcing/5-pushing-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/4-reacting-to-events/1-messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
6 changes: 3 additions & 3 deletions docs/docs/4-reacting-to-events/2-message-queues.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 🤗).

:::

Expand Down Expand Up @@ -82,7 +82,7 @@ const appMessagesWorker = async ({ Records }: SQSMessageQueueMessage) => {
>
> - <code>messageQueueId <i>(string)</i></code>: A string identifying the message queue
> - <code>sourceEventStores <i>(EventStore[])</i></code>: List of event stores that the message queue will broadcast events from
> - <code>messageQueueAdapter <i>(?MessageChannelAdapter)</i></code>: See section on <a href="#messagequeueadapter">MessageQueueAdapters</a>
> - <code>messageQueueAdapter <i>(?MessageChannelAdapter)</i></code>: Message queue adapter
>
> **Properties:**
>
Expand All @@ -100,7 +100,7 @@ const appMessagesWorker = async ({ Records }: SQSMessageQueueMessage) => {
> // => [pokemonsEventStore, trainersEventStore...]
> ```
>
> - <code>messageChannelAdapter <i>?MessageChannelAdapter</i></code>: See section on <a href="#messagequeueadapter">MessageQueueAdapters</a>
> - <code>messageChannelAdapter <i>?MessageChannelAdapter</i></code>: Returns the associated message queue adapter (potentially undefined)
>
> ```ts
> const appMessageQueueAdapter = appMessageQueue.messageChannelAdapter;
Expand Down
6 changes: 3 additions & 3 deletions docs/docs/4-reacting-to-events/3-message-buses.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 🤗).

:::

Expand Down Expand Up @@ -82,7 +82,7 @@ const pokemonMessagesListener = async (
>
> - <code>messageBusId <i>(string)</i></code>: A string identifying the message bus
> - <code>sourceEventStores <i>(EventStore[])</i></code>: List of event stores that the message bus will broadcast events from
> - <code>messageBusAdapter <i>(?MessageChannelAdapter)</i></code>: See section on <a href="#messagebusadapter">MessageBusAdapters</a>
> - <code>messageBusAdapter <i>(?MessageChannelAdapter)</i></code>: Message bus adapter
>
> **Properties:**
>
Expand All @@ -100,7 +100,7 @@ const pokemonMessagesListener = async (
> // => [pokemonsEventStore, trainersEventStore...]
> ```
>
> - <code>messageChannelAdapter <i>?MessageChannelAdapter</i></code>: See section on <a href="#messagebusadapter">MessageBusAdapters</a>
> - <code>messageChannelAdapter <i>?MessageChannelAdapter</i></code>: Returns the associated message bus adapter (potentially undefined)
>
> ```ts
> const appMessageBusAdapter = appMessageBus.messageChannelAdapter;
Expand Down

0 comments on commit f99e47c

Please sign in to comment.