Skip to content

Commit 52ac6c5

Browse files
committed
Simplified getAndUpdate and add methods handling
Removed `Current` from the shopping cart methods
1 parent 753f262 commit 52ac6c5

File tree

15 files changed

+62
-76
lines changed

15 files changed

+62
-76
lines changed

samples/optimisticConcurrency/src/core/eventStore/appending/add.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { Event } from '../../events';
2-
import { EventStoreDBClient, NO_STREAM } from '@eventstore/db-client';
2+
import { NO_STREAM } from '@eventstore/db-client';
33
import { Result } from '../../primitives';
44
import { FAILED_TO_APPEND_EVENT } from '.';
55
import { AppendResult, appendToStream } from './appendToStream';
6+
import { getEventStore } from '..';
67

78
export async function add<
89
Command,
@@ -11,7 +12,6 @@ export async function add<
1112
STORE_ERROR = never
1213
>(
1314
handle: (command: Command) => Result<StreamEvent, HANDLE_ERROR>,
14-
eventStore: EventStoreDBClient,
1515
streamName: string,
1616
command: Command
1717
): Promise<
@@ -23,7 +23,7 @@ export async function add<
2323

2424
const newEvent = handleResult.value;
2525

26-
return appendToStream(eventStore, streamName, [newEvent], {
26+
return appendToStream(getEventStore(), streamName, [newEvent], {
2727
expectedRevision: NO_STREAM,
2828
});
2929
}

samples/optimisticConcurrency/src/core/eventStore/appending/getAndUpdate.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { EventStoreDBClient } from '@eventstore/db-client';
21
import { Event, StreamEvent } from '../../events';
32
import { Command } from '../../commands';
43
import { readFromStream, STREAM_NOT_FOUND } from '../reading';
54
import { appendToStream } from '../appending';
65
import { Result } from '../../primitives';
76
import { AppendResult, FAILED_TO_APPEND_EVENT } from '.';
7+
import { getEventStore } from '..';
88

99
export async function getAndUpdate<
1010
CommandType extends Command,
@@ -15,12 +15,13 @@ export async function getAndUpdate<
1515
currentEvents: StreamEvent<StreamEventType>[],
1616
command: CommandType
1717
) => Result<StreamEventType, HANDLE_ERROR>,
18-
eventStore: EventStoreDBClient,
1918
streamName: string,
2019
command: CommandType
2120
): Promise<
2221
Result<AppendResult, STREAM_NOT_FOUND | FAILED_TO_APPEND_EVENT | HANDLE_ERROR>
2322
> {
23+
const eventStore = getEventStore();
24+
2425
const result = await readFromStream<StreamEventType>(eventStore, streamName);
2526

2627
if (result.isError) return result;

samples/optimisticConcurrency/src/core/http/requests/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { Request } from 'express';
22
import { failure, Result, success } from '../../primitives';
33

4-
export type WeakETag = string;
4+
export type WeakETag = `W/${string}`;
55
export type ETag = WeakETag | string;
66

77
export const WeakETagRegex = /W\/"(\d+.*)"/;
8+
89
export type WRONG_WEAK_ETAG_FORMAT = 'WRONG_WEAK_ETAG_FORMAT';
910
export type MISSING_IF_MATCH_HEADER = 'MISSING_IF_MATCH_HEADER';
1011

@@ -24,7 +25,7 @@ export function toWeakETag(value: any): WeakETag {
2425

2526
export function getETagFromIfMatch(
2627
request: Request
27-
): Result<WeakETag, MISSING_IF_MATCH_HEADER> {
28+
): Result<ETag, MISSING_IF_MATCH_HEADER> {
2829
const etag = request.headers['if-match'];
2930

3031
if (etag === undefined) {
@@ -33,9 +34,9 @@ export function getETagFromIfMatch(
3334
return success(<ETag>etag);
3435
}
3536

36-
export function getWeakETagFromIfMatch(
37+
export function getWeakETagValueFromIfMatch(
3738
request: Request
38-
): Result<WeakETag, WRONG_WEAK_ETAG_FORMAT | MISSING_IF_MATCH_HEADER> {
39+
): Result<string, WRONG_WEAK_ETAG_FORMAT | MISSING_IF_MATCH_HEADER> {
3940
const etag = getETagFromIfMatch(request);
4041

4142
if (etag.isError) return etag;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { getEventStore } from '#core/eventStore';
22
import { getSubscriptionToAllWithESDBCheckpointing } from '#core/eventStore/subscribing';
3-
import { projectToCurrentShoppingCartDetails } from './shoppingCarts/gettingById/projection';
3+
import { projectToShoppingCartDetails } from './shoppingCarts/gettingById/projection';
44

55
export const getSubscription = () =>
66
getSubscriptionToAllWithESDBCheckpointing(getEventStore(), [
7-
projectToCurrentShoppingCartDetails,
7+
projectToShoppingCartDetails,
88
]);

samples/optimisticConcurrency/src/shoppingCarts/addingProductItem/handler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export type AddProductItemToShoppingCart = Command<
2020
}
2121
>;
2222

23-
export function handleAddingProductItemToShoppingCart(
23+
export function addProductItemToShoppingCart(
2424
events: StreamEvent<ShoppingCartEvent>[],
2525
command: AddProductItemToShoppingCart
2626
): Result<ProductItemAddedToShoppingCart, SHOPPING_CARD_CLOSED> {

samples/optimisticConcurrency/src/shoppingCarts/addingProductItem/route.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
11
import { NextFunction, Request, Response, Router } from 'express';
22
import { isCommand } from '#core/commands';
3-
import { handleAddingProductItemToShoppingCart } from './handler';
3+
import { addProductItemToShoppingCart } from './handler';
44
import { getShoppingCartStreamName } from '../shoppingCart';
55
import {
66
isNotEmptyString,
77
isPositiveNumber,
88
ValidationError,
99
} from '#core/validation';
1010
import {
11-
getWeakETagFromIfMatch,
11+
getWeakETagValueFromIfMatch,
1212
toWeakETag,
1313
WRONG_ETAG,
1414
} from '#core/http/requests';
1515
import { AddProductItemToShoppingCart } from '.';
1616
import { getAndUpdate } from '#core/eventStore/appending';
17-
import { getEventStore } from '#core/eventStore';
1817
import { assertUnreachable } from '#core/primitives';
1918

2019
export const route = (router: Router) =>
2120
router.post(
22-
'/clients/:clientId/shopping-carts/:shoppingCartId',
21+
'/clients/:clientId/shopping-carts/:shoppingCartId/product-items',
2322
async function (request: Request, response: Response, next: NextFunction) {
2423
try {
2524
const command = mapRequestToCommand(request);
@@ -33,8 +32,7 @@ export const route = (router: Router) =>
3332
);
3433

3534
const result = await getAndUpdate(
36-
handleAddingProductItemToShoppingCart,
37-
getEventStore(),
35+
addProductItemToShoppingCart,
3836
streamName,
3937
command
4038
);
@@ -75,7 +73,7 @@ function mapRequestToCommand(
7573
return 'INVALID_PRODUCT_ITEM_QUANTITY';
7674
}
7775

78-
const expectedRevision = getWeakETagFromIfMatch(request);
76+
const expectedRevision = getWeakETagValueFromIfMatch(request);
7977

8078
if (expectedRevision.isError) {
8179
return expectedRevision.error;
@@ -84,9 +82,9 @@ function mapRequestToCommand(
8482
return {
8583
type: 'add-product-item-to-shopping-cart',
8684
data: {
87-
shoppingCartId: request.body.shoppingCartId,
85+
shoppingCartId: request.params.shoppingCartId,
8886
productItem: {
89-
productId: request.params.productId,
87+
productId: request.body.productId,
9088
quantity: request.body.quantity,
9189
},
9290
},

samples/optimisticConcurrency/src/shoppingCarts/confirming/handler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export type ConfirmShoppingCart = Command<
1818
}
1919
>;
2020

21-
export function handleConfirmShoppingCart(
21+
export function confirmShoppingCart(
2222
events: StreamEvent<ShoppingCartEvent>[],
2323
command: ConfirmShoppingCart
2424
): Result<ShoppingCartConfirmed, SHOPPING_CARD_CLOSED> {

samples/optimisticConcurrency/src/shoppingCarts/confirming/route.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
import { NextFunction, Request, Response, Router } from 'express';
22
import { isCommand } from '#core/commands';
3-
import { handleConfirmShoppingCart } from './handler';
3+
import { confirmShoppingCart } from './handler';
44
import { getShoppingCartStreamName } from '../shoppingCart';
55
import { isNotEmptyString, ValidationError } from '#core/validation';
66
import {
7-
getWeakETagFromIfMatch,
7+
getWeakETagValueFromIfMatch,
88
toWeakETag,
99
WRONG_ETAG,
1010
} from '#core/http/requests';
1111
import { ConfirmShoppingCart } from '.';
1212
import { getAndUpdate } from '#core/eventStore/appending';
13-
import { getEventStore } from '#core/eventStore';
1413
import { assertUnreachable } from '#core/primitives';
1514

1615
export const route = (router: Router) =>
17-
router.post(
16+
router.put(
1817
'/clients/:clientId/shopping-carts/:shoppingCartId',
1918
async function (request: Request, response: Response, next: NextFunction) {
2019
try {
@@ -29,8 +28,7 @@ export const route = (router: Router) =>
2928
);
3029

3130
const result = await getAndUpdate(
32-
handleConfirmShoppingCart,
33-
getEventStore(),
31+
confirmShoppingCart,
3432
streamName,
3533
command
3634
);
@@ -63,7 +61,7 @@ function mapRequestToCommand(
6361
return 'MISSING_SHOPPING_CARD_ID';
6462
}
6563

66-
const expectedRevision = getWeakETagFromIfMatch(request);
64+
const expectedRevision = getWeakETagValueFromIfMatch(request);
6765

6866
if (expectedRevision.isError) {
6967
return expectedRevision.error;

samples/optimisticConcurrency/src/shoppingCarts/gettingById/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export type ProductItem = Readonly<{
66
quantity: number;
77
}>;
88

9-
export type CurrentShoppingCartDetails = Readonly<{
9+
export type ShoppingCartDetails = Readonly<{
1010
shoppingCartId: string;
1111
clientId: string;
1212
status: string;
@@ -16,4 +16,4 @@ export type CurrentShoppingCartDetails = Readonly<{
1616
revision: string;
1717
}>;
1818

19-
export const CURRENT_SHOPPING_CART_DETAILS = 'currentShoppingCartDetails';
19+
export const SHOPPING_CART_DETAILS = 'shoppingCartDetails';

samples/optimisticConcurrency/src/shoppingCarts/gettingById/projection.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ import {
88
ShoppingCartOpened,
99
ShoppingCartStatus,
1010
} from '..';
11-
import { CurrentShoppingCartDetails, CURRENT_SHOPPING_CART_DETAILS } from '.';
11+
import { ShoppingCartDetails, SHOPPING_CART_DETAILS } from '.';
1212
import { addProductItem, removeProductItem } from '../productItems';
1313

1414
export async function projectShoppingCartOpened(
1515
event: ShoppingCartOpened,
1616
streamRevision: bigint
1717
): Promise<Result<true>> {
18-
await executeOnMongoDB<CurrentShoppingCartDetails>(
19-
{ collectionName: CURRENT_SHOPPING_CART_DETAILS },
18+
await executeOnMongoDB<ShoppingCartDetails>(
19+
{ collectionName: SHOPPING_CART_DETAILS },
2020
async (collection) => {
2121
await collection.insertOne({
2222
shoppingCartId: event.data.shoppingCartId,
@@ -36,8 +36,8 @@ export async function projectProductItemAddedToShoppingCart(
3636
event: ProductItemAddedToShoppingCart,
3737
streamRevision: bigint
3838
): Promise<Result<true>> {
39-
await executeOnMongoDB<CurrentShoppingCartDetails>(
40-
{ collectionName: CURRENT_SHOPPING_CART_DETAILS },
39+
await executeOnMongoDB<ShoppingCartDetails>(
40+
{ collectionName: SHOPPING_CART_DETAILS },
4141
async (collection) => {
4242
const { productItems } = (await collection.findOne(
4343
{
@@ -67,8 +67,8 @@ export async function projectProductItemRemovedFromShoppingCart(
6767
event: ProductItemRemovedFromShoppingCart,
6868
streamRevision: bigint
6969
): Promise<Result<true>> {
70-
await executeOnMongoDB<CurrentShoppingCartDetails>(
71-
{ collectionName: CURRENT_SHOPPING_CART_DETAILS },
70+
await executeOnMongoDB<ShoppingCartDetails>(
71+
{ collectionName: SHOPPING_CART_DETAILS },
7272
async (collection) => {
7373
const { productItems } = (await collection.findOne(
7474
{
@@ -101,8 +101,8 @@ export async function projectShoppingCartConfirmed(
101101
event: ShoppingCartConfirmed,
102102
streamRevision: bigint
103103
): Promise<Result<true>> {
104-
await executeOnMongoDB<CurrentShoppingCartDetails>(
105-
{ collectionName: CURRENT_SHOPPING_CART_DETAILS },
104+
await executeOnMongoDB<ShoppingCartDetails>(
105+
{ collectionName: SHOPPING_CART_DETAILS },
106106
async (collection) => {
107107
await collection.updateOne(
108108
{
@@ -122,16 +122,16 @@ export async function projectShoppingCartConfirmed(
122122
return success(true);
123123
}
124124

125-
type CurrentShoppingCartDetailsEvent =
125+
type ShoppingCartDetailsEvent =
126126
| ShoppingCartOpened
127127
| ProductItemAddedToShoppingCart
128128
| ProductItemRemovedFromShoppingCart
129129
| ShoppingCartConfirmed;
130130

131131
function isCashierShoppingCartDetailsEvent(
132132
event: Event
133-
): event is CurrentShoppingCartDetailsEvent {
134-
const eventType = (event as CurrentShoppingCartDetailsEvent).type;
133+
): event is ShoppingCartDetailsEvent {
134+
const eventType = (event as ShoppingCartDetailsEvent).type;
135135

136136
return (
137137
eventType === 'shopping-cart-opened' ||
@@ -141,7 +141,7 @@ function isCashierShoppingCartDetailsEvent(
141141
);
142142
}
143143

144-
export async function projectToCurrentShoppingCartDetails(
144+
export async function projectToShoppingCartDetails(
145145
streamEvent: StreamEvent
146146
): Promise<Result<boolean>> {
147147
const { event, streamRevision } = streamEvent;

0 commit comments

Comments
 (0)