Releases: event-driven-io/emmett
0.12.1
📝 What's Changed
- Fixed mapping of optimistic concurrency for PostgreSQL event store by @oskardudycz in #88
Full Changelog: 0.12.0...0.12.1
0.12.0
🚀 What's New
- Boom! 💣 🔥 🐘 Added a first experimental implementation of PostgreSQL inline projections. by @oskardudycz in #90
You can do it e.g with:
type ShoppingCartShortInfo = {
productItemsCount: number;
totalAmount: number;
};
const shoppingCartShortInfoCollectionName = 'shoppingCartShortInfo';
const evolve = (
document: ShoppingCartShortInfo | null,
{ type, data: event }: ProductItemAdded | DiscountApplied,
): ShoppingCartShortInfo => {
document = document ?? { productItemsCount: 0, totalAmount: 0 };
switch (type) {
case 'ProductItemAdded':
return {
totalAmount:
document.totalAmount +
event.productItem.price * event.productItem.quantity,
productItemsCount:
document.productItemsCount + event.productItem.quantity,
};
case 'DiscountApplied':
return {
...document,
totalAmount: (document.totalAmount * (100 - event.percent)) / 100,
};
}
};
const shoppingCartShortInfoProjection = pongoSingleProjection(
shoppingCartShortInfoCollectionName,
evolve,
'ProductItemAdded',
'DiscountApplied',
);
Then register it as:
import { getPool, getPostgreSQLEventStore } from '@event-driven-io/emmett-postgresql';
const connectionString =
"postgresql://dbuser:[email protected]:3211/mydb";
const eventStore = getPostgreSQLEventStore(connectionString, {
projections: [shoppingCartShortInfoProjection],
});
And read models will be updated in the same transaction as appended events.
const shoppingCartId = `shopping_cart-${uuid()}`;
const productItem: PricedProductItem = {
productId: '123',
quantity: 10,
price: 3,
};
await eventStore.appendToStream<ShoppingCartEvent>(shoppingCartId, [
{ type: 'ProductItemAdded', data: { productItem } },
]);
const shoppingCartShortInfo = pongo
.db()
.collection<ShoppingCartShortInfo>(shoppingCartShortInfoCollectionName);
const document = await shoppingCartShortInfo.findOne({ _id: shoppingCartId });
📝 What's Changed
- Added sample showing PostgreSQL event store by @oskardudycz in #87
- Used code from Dumbo instead of duplicated one between Emmett and Pongo by @oskardudycz in #89
Full Changelog: 0.12.1...0.13.0
0.11.2
📝 What's Changed
- Fixed in-memory message bus declaration to correctly expose command and event processor methods. Added missing explicit definition that message bus is also Event and Command processor. by @oskardudycz in #83
Full Changelog: 0.11.1...0.11.2
0.11.1
📝 What's Changed
- Added missing exports for MessageBus. It appeared that I forgot to export the
MessageBus
related code in the main index file, and then they were trimmed by tree shaking during publishing. Now they're correctly exported. by @oskardudycz in #82
Full Changelog: 0.11.0...0.11.1
0.11.0
🚀 What's New
- Exposed WrapEventStore and TestEventStream. This can be helpful for people wanting to write their own way of testing or perform diagnostics around newly added events. by @oskardudycz in #81
Full Changelog: 0.10.0...0.11.0
0.10.0
🚀 What's New
-
Added example showing how to run Emmett application in Docker container. It shows the full setup with running WebApi, building Docker image with bundling etc. by @oskardudycz in #67
-
BREAKING: Aligned initial state naming for state aggregation. It wasn't consistent, sometimes it was called
initialState
, sometimesgetInitialState
. Now all is aligned toinitialState
by @oskardudycz in #80 -
Extended
thenThrows
in DeciderSpecification to handle type checks. Now it allows multiple options like:- just checking if the error was thrown,
- if it is of the specified type,
- if matches condition,
- if it is of the specified type and matches the condition.
by @oskardudycz in #72
-
Added returning events from the command handler. Now, besides the new state, you'll also get new events in the command handler result. Note: The returned events are raw domain events without the metadata assigned by the event store during appending. by @oskardudycz in #73
-
Updated
CreatedHttpResponse
not to require bothcreatedId
andURL
but allow providing either of them. Sometimes there's no clear recordid
to return, so forcing the user to providecreatedId
is redundant. Just redirect is fine. by @oskardudycz in #71 -
Exposed Typed
TestRequest
for API integration and E2E tests Now, it's possible to provide a named setup without referencingsupertest
in the end project. For instance
const openedShoppingCartWithProduct: TestRequest = (request) =>
request
.post(`/clients/${clientId}/shopping-carts/current/product-items`)
.send(productItem);
by @oskardudycz in #77
- Added helpers for parsing and validating dates in
yyyy-mm-dd
format You can now useformatDateToUtcYYYYMMDD
,isValidYYYYMMDD
,parseDateFromUtcYYYYMMDD
. It can be useful for validation or parsing incoming web API data in a standardised way. by @oskardudycz in #78 - Added assertions to not need to use built-in Node to make it compatible with browsers by @oskardudycz in #79
- Added implementation of restreaming and shim for WebStreams API. This is the first step toward subscription handling by @oskardudycz in #70, #68
📝 What's Changed
- Requiring only partial problem details in expectError helper for API and Integration tests by @oskardudycz in #75
Full Changelog: 0.9.0...0.10.0
0.9.0
🚀 What's New
- Allow Custom
appendToStream
options when usingCommandHandler
Now you can extend the command handler to take your own event store implementation that supersets the default event store definition by @alex-laycalvert in #63
📝 What's Changed
- Removed
node
packages usage in core Emmett package. It appeared in #64 that, by accident, the in-memory event store was usingrandomUUID
fromnode:crypto
, which was causing compatibility issues on the web. Added also the ESLint rule to prevent such things to happen in the future. by @oskardudycz in #66 - Fixed configuration for a single file debugging by @oskardudycz in #65
New Contributors
- @alex-laycalvert made their first contribution in #63
Full Changelog: 0.8.0...0.9.0
0.8.0
🚀 What's New
- Added default handling of EventStoreDB test container ARM64 image. That should make the Mac M1 setup easier. Also changed EventStoreDB test container options to be in the nested object and false by default. That should make them more straightforward. by @oskardudycz in #62
Full Changelog: 0.7.1...0.8.0
0.7.1
📝 What's Changed
- Fixed CommonJs import issues by making event store features tests internal not to expose node packages in bundled Emmett code. It appeared that
tsup
andesbuild
used internally as code bundlers are strippingnode:
prefix for non-node targets, causing compatibility issues for CommonJs modules. Made internal code that was exposing it in code bundle. by @oskardudycz in #61, #59 - Fixed the linter issue with
no-floating-promise
rule in tests. It seems that markingdescribes
andit
with avoid
keyword fixes the issue and still allows floating promises to be caught in the test code. by @oskardudycz in #61, #16
Full Changelog: 0.7.0...0.7.1
0.7.0
🚀 What's New
-
Added in-memory Message Bus implementation. It's a small step towards handling read models and subscriptions in Emmett. It allows publishing events, sending commands, and handling them in memory. Read more in the article How to build an in-memory Message Bus in TypeScript by @oskardudycz in #58
Basic usage:
import { getInMemoryMessageBus } from '@event-driven-io/emmett'; const messageBus = getInMemoryMessageBus();
registering handlers:
messageBus.subscribe( handleGuestStay, 'GuestCheckedIn', 'ChargeRecorded', 'GuestCheckedOut', 'GuestCheckoutFailed', );
And publishing new event:
const event:GuestCheckedOut = { type: 'GuestCheckedOut', data: { guestStayAccountId: 'r9293'; checkedOutAt: new Date(); } >; await messageBus.publish(event);
Full Changelog: 0.6.0...0.7.0