@event-driven-io/emmett 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commandHandling/handleCommand.d.mts +6 -3
- package/dist/commandHandling/handleCommand.d.ts +6 -3
- package/dist/commandHandling/handleCommand.js +33 -29
- package/dist/commandHandling/handleCommand.js.map +1 -1
- package/dist/commandHandling/handleCommand.mjs +4 -2
- package/dist/commandHandling/handleCommand.mjs.map +1 -1
- package/dist/commandHandling/handleCommand.unit.spec.js +83 -0
- package/dist/commandHandling/handleCommand.unit.spec.js.map +1 -0
- package/dist/commandHandling/handleCommand.unit.spec.mjs +93 -0
- package/dist/commandHandling/handleCommand.unit.spec.mjs.map +1 -0
- package/dist/commandHandling/handleCommandWithDecider.d.mts +3 -2
- package/dist/commandHandling/handleCommandWithDecider.d.ts +3 -2
- package/dist/commandHandling/handleCommandWithDecider.js +4 -13
- package/dist/commandHandling/handleCommandWithDecider.js.map +1 -1
- package/dist/commandHandling/index.d.mts +1 -1
- package/dist/commandHandling/index.d.ts +1 -1
- package/dist/commandHandling/index.js +2 -2
- package/dist/commandHandling/index.js.map +1 -1
- package/dist/errors/index.js +67 -51
- package/dist/errors/index.js.map +1 -1
- package/dist/eventStore/eventStore.js +2 -1
- package/dist/eventStore/eventStore.js.map +1 -1
- package/dist/eventStore/expectedVersion.js +22 -29
- package/dist/eventStore/expectedVersion.js.map +1 -1
- package/dist/eventStore/expectedVersion.unit.spec.js +48 -60
- package/dist/eventStore/expectedVersion.unit.spec.js.map +1 -1
- package/dist/eventStore/inMemoryEventStore.js +65 -64
- package/dist/eventStore/inMemoryEventStore.js.map +1 -1
- package/dist/eventStore/inMemoryEventStore.mjs +6 -1
- package/dist/eventStore/inMemoryEventStore.mjs.map +1 -1
- package/dist/eventStore/inMemoryEventStore.unit.spec.d.mts +2 -0
- package/dist/eventStore/inMemoryEventStore.unit.spec.d.ts +2 -0
- package/dist/eventStore/inMemoryEventStore.unit.spec.js +85 -0
- package/dist/eventStore/inMemoryEventStore.unit.spec.js.map +1 -0
- package/dist/eventStore/inMemoryEventStore.unit.spec.mjs +81 -0
- package/dist/eventStore/inMemoryEventStore.unit.spec.mjs.map +1 -0
- package/dist/eventStore/index.js +3 -3
- package/dist/eventStore/index.js.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/serialization/index.js +1 -1
- package/dist/serialization/index.js.map +1 -1
- package/dist/serialization/json/JSONParser.js +16 -20
- package/dist/serialization/json/JSONParser.js.map +1 -1
- package/dist/serialization/json/index.js +1 -1
- package/dist/serialization/json/index.js.map +1 -1
- package/dist/testing/assertions.js +12 -24
- package/dist/testing/assertions.js.map +1 -1
- package/dist/testing/deciderSpecification.js +40 -39
- package/dist/testing/deciderSpecification.js.map +1 -1
- package/dist/testing/index.js +2 -2
- package/dist/testing/index.js.map +1 -1
- package/dist/typing/command.js +2 -1
- package/dist/typing/command.js.map +1 -1
- package/dist/typing/decider.js +2 -1
- package/dist/typing/decider.js.map +1 -1
- package/dist/typing/event.js +2 -1
- package/dist/typing/event.js.map +1 -1
- package/dist/typing/index.js +4 -4
- package/dist/typing/index.js.map +1 -1
- package/dist/typing/workflow.d.ts +57 -1
- package/dist/typing/workflow.js +45 -55
- package/dist/typing/workflow.js.map +1 -1
- package/dist/utils/index.js +3 -6
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/iterators.js +8 -10
- package/dist/utils/iterators.js.map +1 -1
- package/dist/utils/merge.js +27 -21
- package/dist/utils/merge.js.map +1 -1
- package/dist/validation/index.js +25 -33
- package/dist/validation/index.js.map +1 -1
- package/dist/validation/validation.spec.js +14 -10
- package/dist/validation/validation.spec.js.map +1 -1
- package/package.json +1 -1
- package/dist/testing/placeholder.e2e.spec.js +0 -8
- package/dist/testing/placeholder.e2e.spec.js.map +0 -1
- package/dist/testing/placeholder.e2e.spec.mjs +0 -8
- package/dist/testing/placeholder.e2e.spec.mjs.map +0 -1
- /package/dist/{testing/placeholder.e2e.spec.d.mts → commandHandling/handleCommand.unit.spec.d.mts} +0 -0
- /package/dist/{testing/placeholder.e2e.spec.d.ts → commandHandling/handleCommand.unit.spec.d.ts} +0 -0
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { D as DefaultStreamVersionType, d as AppendToStreamResult, E as EventStore, e as ExpectedStreamVersion } from '../eventStore-DLezSgsV.mjs';
|
|
2
2
|
import { Event } from '../typing/index.mjs';
|
|
3
3
|
import '../errors/index.mjs';
|
|
4
4
|
|
|
5
|
+
type CommandHandlerResult<State, StreamVersion = DefaultStreamVersionType> = AppendToStreamResult<StreamVersion> & {
|
|
6
|
+
newState: State;
|
|
7
|
+
};
|
|
5
8
|
declare const CommandHandler: <State, StreamEvent extends Event, StreamVersion = bigint>(evolve: (state: State, event: StreamEvent) => State, getInitialState: () => State, mapToStreamId?: (id: string) => string) => (eventStore: EventStore<StreamVersion>, id: string, handle: (state: State) => StreamEvent | StreamEvent[], options?: {
|
|
6
9
|
expectedStreamVersion?: ExpectedStreamVersion<StreamVersion> | undefined;
|
|
7
|
-
} | undefined) => Promise<
|
|
10
|
+
} | undefined) => Promise<CommandHandlerResult<State, StreamVersion>>;
|
|
8
11
|
|
|
9
|
-
export { CommandHandler };
|
|
12
|
+
export { CommandHandler, type CommandHandlerResult };
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { D as DefaultStreamVersionType, d as AppendToStreamResult, E as EventStore, e as ExpectedStreamVersion } from '../eventStore-N_YMFCDT.js';
|
|
2
2
|
import { Event } from '../typing/index.js';
|
|
3
3
|
import '../errors/index.js';
|
|
4
4
|
|
|
5
|
+
type CommandHandlerResult<State, StreamVersion = DefaultStreamVersionType> = AppendToStreamResult<StreamVersion> & {
|
|
6
|
+
newState: State;
|
|
7
|
+
};
|
|
5
8
|
declare const CommandHandler: <State, StreamEvent extends Event, StreamVersion = bigint>(evolve: (state: State, event: StreamEvent) => State, getInitialState: () => State, mapToStreamId?: (id: string) => string) => (eventStore: EventStore<StreamVersion>, id: string, handle: (state: State) => StreamEvent | StreamEvent[], options?: {
|
|
6
9
|
expectedStreamVersion?: ExpectedStreamVersion<StreamVersion> | undefined;
|
|
7
|
-
} | undefined) => Promise<
|
|
10
|
+
} | undefined) => Promise<CommandHandlerResult<State, StreamVersion>>;
|
|
8
11
|
|
|
9
|
-
export { CommandHandler };
|
|
12
|
+
export { CommandHandler, type CommandHandlerResult };
|
|
@@ -1,31 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
1
|
+
import { NO_CONCURRENCY_CHECK, STREAM_DOES_NOT_EXIST, } from '../eventStore';
|
|
2
|
+
export const CommandHandler = (evolve, getInitialState, mapToStreamId = (id) => id) => async (eventStore, id, handle, options) => {
|
|
3
|
+
const streamName = mapToStreamId(id);
|
|
4
|
+
// 1. Aggregate the stream
|
|
5
|
+
const aggregationResult = await eventStore.aggregateStream(streamName, {
|
|
6
|
+
evolve,
|
|
7
|
+
getInitialState,
|
|
8
|
+
read: {
|
|
9
|
+
// expected stream version is passed to fail fast
|
|
10
|
+
// if stream is in the wrong state
|
|
11
|
+
expectedStreamVersion: options?.expectedStreamVersion ?? NO_CONCURRENCY_CHECK,
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
// 2. Use the aggregate state or the initial one (when e.g. stream does not exist)
|
|
15
|
+
const state = aggregationResult?.state ?? getInitialState();
|
|
16
|
+
const currentStreamVersion = aggregationResult?.currentStreamVersion;
|
|
17
|
+
// 3. Run business logic
|
|
18
|
+
const result = handle(state);
|
|
19
|
+
const newEvents = Array.isArray(result) ? result : [result];
|
|
20
|
+
// Either use:
|
|
21
|
+
// - provided expected stream version,
|
|
22
|
+
// - current stream version got from stream aggregation,
|
|
23
|
+
// - or expect stream not to exists otherwise.
|
|
24
|
+
const expectedStreamVersion = options?.expectedStreamVersion ??
|
|
25
|
+
currentStreamVersion ??
|
|
26
|
+
STREAM_DOES_NOT_EXIST;
|
|
27
|
+
// 4. Append result to the stream
|
|
28
|
+
const appendResult = await eventStore.appendToStream(streamName, newEvents, {
|
|
29
|
+
expectedStreamVersion,
|
|
30
|
+
});
|
|
31
|
+
// 5. Return result with updated state
|
|
32
|
+
return { ...appendResult, newState: newEvents.reduce(evolve, state) };
|
|
27
33
|
};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
exports.CommandHandler = CommandHandler;
|
|
34
|
+
// #endregion command-handler
|
|
31
35
|
//# sourceMappingURL=handleCommand.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commandHandling/handleCommand.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"handleCommand.js","sourceRoot":"","sources":["../../src/commandHandling/handleCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GAKtB,MAAM,eAAe,CAAC;AASvB,MAAM,CAAC,MAAM,cAAc,GACzB,CACE,MAAmD,EACnD,eAA4B,EAC5B,gBAAwC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAClD,EAAE,CACJ,KAAK,EACH,UAAqC,EACrC,EAAU,EACV,MAAqD,EACrD,OAEC,EACoD,EAAE;IACvD,MAAM,UAAU,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;IAErC,0BAA0B;IAC1B,MAAM,iBAAiB,GAAG,MAAM,UAAU,CAAC,eAAe,CAGxD,UAAU,EAAE;QACZ,MAAM;QACN,eAAe;QACf,IAAI,EAAE;YACJ,iDAAiD;YACjD,kCAAkC;YAClC,qBAAqB,EACnB,OAAO,EAAE,qBAAqB,IAAI,oBAAoB;SACzD;KACF,CAAC,CAAC;IAEH,kFAAkF;IAClF,MAAM,KAAK,GAAG,iBAAiB,EAAE,KAAK,IAAI,eAAe,EAAE,CAAC;IAC5D,MAAM,oBAAoB,GAAG,iBAAiB,EAAE,oBAAoB,CAAC;IAErE,wBAAwB;IACxB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE7B,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAE5D,cAAc;IACd,sCAAsC;IACtC,wDAAwD;IACxD,8CAA8C;IAC9C,MAAM,qBAAqB,GACzB,OAAO,EAAE,qBAAqB;QAC9B,oBAAoB;QACpB,qBAAqB,CAAC;IAExB,iCAAiC;IACjC,MAAM,YAAY,GAAG,MAAM,UAAU,CAAC,cAAc,CAClD,UAAU,EACV,SAAS,EACT;QACE,qBAAqB;KACtB,CACF,CAAC;IAEF,sCAAsC;IACtC,OAAO,EAAE,GAAG,YAAY,EAAE,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;AACxE,CAAC,CAAC;AACJ,6BAA6B"}
|
|
@@ -16,14 +16,16 @@ const CommandHandler = (evolve, getInitialState, mapToStreamId = (id) => id) =>
|
|
|
16
16
|
const state = aggregationResult?.state ?? getInitialState();
|
|
17
17
|
const currentStreamVersion = aggregationResult?.currentStreamVersion;
|
|
18
18
|
const result = handle(state);
|
|
19
|
+
const newEvents = Array.isArray(result) ? result : [result];
|
|
19
20
|
const expectedStreamVersion = options?.expectedStreamVersion ?? currentStreamVersion ?? STREAM_DOES_NOT_EXIST;
|
|
20
|
-
|
|
21
|
+
const appendResult = await eventStore.appendToStream(
|
|
21
22
|
streamName,
|
|
22
|
-
|
|
23
|
+
newEvents,
|
|
23
24
|
{
|
|
24
25
|
expectedStreamVersion
|
|
25
26
|
}
|
|
26
27
|
);
|
|
28
|
+
return { ...appendResult, newState: newEvents.reduce(evolve, state) };
|
|
27
29
|
};
|
|
28
30
|
export {
|
|
29
31
|
CommandHandler
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commandHandling/handleCommand.ts"],"sourcesContent":["import {\n NO_CONCURRENCY_CHECK,\n STREAM_DOES_NOT_EXIST,\n type DefaultStreamVersionType,\n type EventStore,\n type ExpectedStreamVersion,\n} from '../eventStore';\nimport type { Event } from '../typing';\n\n// #region command-handler\nexport const CommandHandler =\n <State, StreamEvent extends Event, StreamVersion = DefaultStreamVersionType>(\n evolve: (state: State, event: StreamEvent) => State,\n getInitialState: () => State,\n mapToStreamId: (id: string) => string = (id) => id,\n ) =>\n async (\n eventStore: EventStore<StreamVersion>,\n id: string,\n handle: (state: State) => StreamEvent | StreamEvent[],\n options?: {\n expectedStreamVersion?: ExpectedStreamVersion<StreamVersion>;\n },\n ) => {\n const streamName = mapToStreamId(id);\n\n // 1. Aggregate the stream\n const aggregationResult = await eventStore.aggregateStream<\n State,\n StreamEvent\n >(streamName, {\n evolve,\n getInitialState,\n read: {\n // expected stream version is passed to fail fast\n // if stream is in the wrong state\n expectedStreamVersion:\n options?.expectedStreamVersion ?? NO_CONCURRENCY_CHECK,\n },\n });\n\n // 2. Use the aggregate state or the initial one (when e.g. stream does not exist)\n const state = aggregationResult?.state ?? getInitialState();\n const currentStreamVersion = aggregationResult?.currentStreamVersion;\n\n // 3. Run business logic\n const result = handle(state);\n\n // Either use:\n // - provided expected stream version,\n // - current stream version got from stream aggregation,\n // - or expect stream not to exists otherwise.\n const expectedStreamVersion: ExpectedStreamVersion<StreamVersion> =\n options?.expectedStreamVersion ??\n currentStreamVersion ??\n STREAM_DOES_NOT_EXIST;\n\n // 4. Append result to the stream\n
|
|
1
|
+
{"version":3,"sources":["../../src/commandHandling/handleCommand.ts"],"sourcesContent":["import {\n NO_CONCURRENCY_CHECK,\n STREAM_DOES_NOT_EXIST,\n type AppendToStreamResult,\n type DefaultStreamVersionType,\n type EventStore,\n type ExpectedStreamVersion,\n} from '../eventStore';\nimport type { Event } from '../typing';\n\n// #region command-handler\nexport type CommandHandlerResult<\n State,\n StreamVersion = DefaultStreamVersionType,\n> = AppendToStreamResult<StreamVersion> & { newState: State };\n\nexport const CommandHandler =\n <State, StreamEvent extends Event, StreamVersion = DefaultStreamVersionType>(\n evolve: (state: State, event: StreamEvent) => State,\n getInitialState: () => State,\n mapToStreamId: (id: string) => string = (id) => id,\n ) =>\n async (\n eventStore: EventStore<StreamVersion>,\n id: string,\n handle: (state: State) => StreamEvent | StreamEvent[],\n options?: {\n expectedStreamVersion?: ExpectedStreamVersion<StreamVersion>;\n },\n ): Promise<CommandHandlerResult<State, StreamVersion>> => {\n const streamName = mapToStreamId(id);\n\n // 1. Aggregate the stream\n const aggregationResult = await eventStore.aggregateStream<\n State,\n StreamEvent\n >(streamName, {\n evolve,\n getInitialState,\n read: {\n // expected stream version is passed to fail fast\n // if stream is in the wrong state\n expectedStreamVersion:\n options?.expectedStreamVersion ?? NO_CONCURRENCY_CHECK,\n },\n });\n\n // 2. Use the aggregate state or the initial one (when e.g. stream does not exist)\n const state = aggregationResult?.state ?? getInitialState();\n const currentStreamVersion = aggregationResult?.currentStreamVersion;\n\n // 3. Run business logic\n const result = handle(state);\n\n const newEvents = Array.isArray(result) ? result : [result];\n\n // Either use:\n // - provided expected stream version,\n // - current stream version got from stream aggregation,\n // - or expect stream not to exists otherwise.\n const expectedStreamVersion: ExpectedStreamVersion<StreamVersion> =\n options?.expectedStreamVersion ??\n currentStreamVersion ??\n STREAM_DOES_NOT_EXIST;\n\n // 4. Append result to the stream\n const appendResult = await eventStore.appendToStream(\n streamName,\n newEvents,\n {\n expectedStreamVersion,\n },\n );\n\n // 5. Return result with updated state\n return { ...appendResult, newState: newEvents.reduce(evolve, state) };\n };\n// #endregion command-handler\n"],"mappings":"AAAA;AAAA,EACE;AAAA,EACA;AAAA,OAKK;AASA,MAAM,iBACX,CACE,QACA,iBACA,gBAAwC,CAAC,OAAO,OAElD,OACE,YACA,IACA,QACA,YAGwD;AACxD,QAAM,aAAa,cAAc,EAAE;AAGnC,QAAM,oBAAoB,MAAM,WAAW,gBAGzC,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA,MAAM;AAAA;AAAA;AAAA,MAGJ,uBACE,SAAS,yBAAyB;AAAA,IACtC;AAAA,EACF,CAAC;AAGD,QAAM,QAAQ,mBAAmB,SAAS,gBAAgB;AAC1D,QAAM,uBAAuB,mBAAmB;AAGhD,QAAM,SAAS,OAAO,KAAK;AAE3B,QAAM,YAAY,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AAM1D,QAAM,wBACJ,SAAS,yBACT,wBACA;AAGF,QAAM,eAAe,MAAM,WAAW;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,MACE;AAAA,IACF;AAAA,EACF;AAGA,SAAO,EAAE,GAAG,cAAc,UAAU,UAAU,OAAO,QAAQ,KAAK,EAAE;AACtE;","names":[]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-floating-promises */
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import { describe, it } from 'node:test';
|
|
5
|
+
import { getInMemoryEventStore } from '../eventStore';
|
|
6
|
+
import {} from '../typing';
|
|
7
|
+
import { CommandHandler } from './handleCommand';
|
|
8
|
+
const evolve = (state, { type, data }) => {
|
|
9
|
+
switch (type) {
|
|
10
|
+
case 'ProductItemAdded': {
|
|
11
|
+
const productItem = data.productItem;
|
|
12
|
+
return {
|
|
13
|
+
productItems: [...state.productItems, productItem],
|
|
14
|
+
totalAmount: state.totalAmount + productItem.price * productItem.quantity,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
case 'DiscountApplied':
|
|
18
|
+
return {
|
|
19
|
+
...state,
|
|
20
|
+
totalAmount: state.totalAmount * (1 - data.percent),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
const getInitialState = () => {
|
|
25
|
+
return { productItems: [], totalAmount: 0 };
|
|
26
|
+
};
|
|
27
|
+
const addProductItem = (command, _state) => {
|
|
28
|
+
return {
|
|
29
|
+
type: 'ProductItemAdded',
|
|
30
|
+
data: { productItem: command.data.productItem },
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
const defaultDiscount = 0.1;
|
|
34
|
+
const addProductItemWithDiscount = (command, _state) => {
|
|
35
|
+
return [
|
|
36
|
+
{
|
|
37
|
+
type: 'ProductItemAdded',
|
|
38
|
+
data: { productItem: command.data.productItem },
|
|
39
|
+
},
|
|
40
|
+
{ type: 'DiscountApplied', data: { percent: defaultDiscount } },
|
|
41
|
+
];
|
|
42
|
+
};
|
|
43
|
+
const handleCommand = CommandHandler(evolve, getInitialState);
|
|
44
|
+
describe('Command Handler', () => {
|
|
45
|
+
const eventStore = getInMemoryEventStore();
|
|
46
|
+
it('When called successfuly returns new state for a single returned event', async () => {
|
|
47
|
+
const productItem = {
|
|
48
|
+
productId: '123',
|
|
49
|
+
quantity: 10,
|
|
50
|
+
price: 3,
|
|
51
|
+
};
|
|
52
|
+
const shoppingCartId = randomUUID();
|
|
53
|
+
const command = {
|
|
54
|
+
type: 'AddProductItem',
|
|
55
|
+
data: { productItem },
|
|
56
|
+
};
|
|
57
|
+
const { nextExpectedStreamVersion, newState } = await handleCommand(eventStore, shoppingCartId, (state) => addProductItem(command, state));
|
|
58
|
+
assert.deepEqual(newState, {
|
|
59
|
+
productItems: [productItem],
|
|
60
|
+
totalAmount: productItem.price * productItem.quantity,
|
|
61
|
+
});
|
|
62
|
+
assert.equal(nextExpectedStreamVersion, 1);
|
|
63
|
+
});
|
|
64
|
+
it('When called successfuly returns new state for multiple returned events', async () => {
|
|
65
|
+
const productItem = {
|
|
66
|
+
productId: '123',
|
|
67
|
+
quantity: 10,
|
|
68
|
+
price: 3,
|
|
69
|
+
};
|
|
70
|
+
const shoppingCartId = randomUUID();
|
|
71
|
+
const command = {
|
|
72
|
+
type: 'AddProductItem',
|
|
73
|
+
data: { productItem },
|
|
74
|
+
};
|
|
75
|
+
const { nextExpectedStreamVersion, newState } = await handleCommand(eventStore, shoppingCartId, (state) => addProductItemWithDiscount(command, state));
|
|
76
|
+
assert.deepEqual(newState, {
|
|
77
|
+
productItems: [productItem],
|
|
78
|
+
totalAmount: productItem.price * productItem.quantity * (1 - defaultDiscount),
|
|
79
|
+
});
|
|
80
|
+
assert.equal(nextExpectedStreamVersion, 2);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
//# sourceMappingURL=handleCommand.unit.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handleCommand.unit.spec.js","sourceRoot":"","sources":["../../src/commandHandling/handleCommand.unit.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { describe, it } from "node:test";
|
|
4
|
+
import { getInMemoryEventStore } from "../eventStore";
|
|
5
|
+
import {} from "../typing";
|
|
6
|
+
import { CommandHandler } from "./handleCommand";
|
|
7
|
+
const evolve = (state, { type, data }) => {
|
|
8
|
+
switch (type) {
|
|
9
|
+
case "ProductItemAdded": {
|
|
10
|
+
const productItem = data.productItem;
|
|
11
|
+
return {
|
|
12
|
+
productItems: [...state.productItems, productItem],
|
|
13
|
+
totalAmount: state.totalAmount + productItem.price * productItem.quantity
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
case "DiscountApplied":
|
|
17
|
+
return {
|
|
18
|
+
...state,
|
|
19
|
+
totalAmount: state.totalAmount * (1 - data.percent)
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const getInitialState = () => {
|
|
24
|
+
return { productItems: [], totalAmount: 0 };
|
|
25
|
+
};
|
|
26
|
+
const addProductItem = (command, _state) => {
|
|
27
|
+
return {
|
|
28
|
+
type: "ProductItemAdded",
|
|
29
|
+
data: { productItem: command.data.productItem }
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
const defaultDiscount = 0.1;
|
|
33
|
+
const addProductItemWithDiscount = (command, _state) => {
|
|
34
|
+
return [
|
|
35
|
+
{
|
|
36
|
+
type: "ProductItemAdded",
|
|
37
|
+
data: { productItem: command.data.productItem }
|
|
38
|
+
},
|
|
39
|
+
{ type: "DiscountApplied", data: { percent: defaultDiscount } }
|
|
40
|
+
];
|
|
41
|
+
};
|
|
42
|
+
const handleCommand = CommandHandler(
|
|
43
|
+
evolve,
|
|
44
|
+
getInitialState
|
|
45
|
+
);
|
|
46
|
+
describe("Command Handler", () => {
|
|
47
|
+
const eventStore = getInMemoryEventStore();
|
|
48
|
+
it("When called successfuly returns new state for a single returned event", async () => {
|
|
49
|
+
const productItem = {
|
|
50
|
+
productId: "123",
|
|
51
|
+
quantity: 10,
|
|
52
|
+
price: 3
|
|
53
|
+
};
|
|
54
|
+
const shoppingCartId = randomUUID();
|
|
55
|
+
const command = {
|
|
56
|
+
type: "AddProductItem",
|
|
57
|
+
data: { productItem }
|
|
58
|
+
};
|
|
59
|
+
const { nextExpectedStreamVersion, newState } = await handleCommand(
|
|
60
|
+
eventStore,
|
|
61
|
+
shoppingCartId,
|
|
62
|
+
(state) => addProductItem(command, state)
|
|
63
|
+
);
|
|
64
|
+
assert.deepEqual(newState, {
|
|
65
|
+
productItems: [productItem],
|
|
66
|
+
totalAmount: productItem.price * productItem.quantity
|
|
67
|
+
});
|
|
68
|
+
assert.equal(nextExpectedStreamVersion, 1);
|
|
69
|
+
});
|
|
70
|
+
it("When called successfuly returns new state for multiple returned events", async () => {
|
|
71
|
+
const productItem = {
|
|
72
|
+
productId: "123",
|
|
73
|
+
quantity: 10,
|
|
74
|
+
price: 3
|
|
75
|
+
};
|
|
76
|
+
const shoppingCartId = randomUUID();
|
|
77
|
+
const command = {
|
|
78
|
+
type: "AddProductItem",
|
|
79
|
+
data: { productItem }
|
|
80
|
+
};
|
|
81
|
+
const { nextExpectedStreamVersion, newState } = await handleCommand(
|
|
82
|
+
eventStore,
|
|
83
|
+
shoppingCartId,
|
|
84
|
+
(state) => addProductItemWithDiscount(command, state)
|
|
85
|
+
);
|
|
86
|
+
assert.deepEqual(newState, {
|
|
87
|
+
productItems: [productItem],
|
|
88
|
+
totalAmount: productItem.price * productItem.quantity * (1 - defaultDiscount)
|
|
89
|
+
});
|
|
90
|
+
assert.equal(nextExpectedStreamVersion, 2);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
//# sourceMappingURL=handleCommand.unit.spec.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/commandHandling/handleCommand.unit.spec.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-floating-promises */\nimport assert from 'node:assert';\nimport { randomUUID } from 'node:crypto';\nimport { describe, it } from 'node:test';\nimport { getInMemoryEventStore } from '../eventStore';\nimport { type Event } from '../typing';\nimport { CommandHandler } from './handleCommand';\n\n// Events & Entity\n\ntype PricedProductItem = { productId: string; quantity: number; price: number };\n\ntype ShoppingCart = {\n productItems: PricedProductItem[];\n totalAmount: number;\n};\n\ntype ProductItemAdded = Event<\n 'ProductItemAdded',\n { productItem: PricedProductItem }\n>;\ntype DiscountApplied = Event<'DiscountApplied', { percent: number }>;\n\ntype ShoppingCartEvent = ProductItemAdded | DiscountApplied;\n\nconst evolve = (\n state: ShoppingCart,\n { type, data }: ShoppingCartEvent,\n): ShoppingCart => {\n switch (type) {\n case 'ProductItemAdded': {\n const productItem = data.productItem;\n return {\n productItems: [...state.productItems, productItem],\n totalAmount:\n state.totalAmount + productItem.price * productItem.quantity,\n };\n }\n case 'DiscountApplied':\n return {\n ...state,\n totalAmount: state.totalAmount * (1 - data.percent),\n };\n }\n};\n\nconst getInitialState = (): ShoppingCart => {\n return { productItems: [], totalAmount: 0 };\n};\n\n// Decision making\n\ntype AddProductItem = Event<\n 'AddProductItem',\n { productItem: PricedProductItem }\n>;\n\nconst addProductItem = (\n command: AddProductItem,\n _state: ShoppingCart,\n): ShoppingCartEvent => {\n return {\n type: 'ProductItemAdded',\n data: { productItem: command.data.productItem },\n };\n};\n\nconst defaultDiscount = 0.1;\n\nconst addProductItemWithDiscount = (\n command: AddProductItem,\n _state: ShoppingCart,\n): ShoppingCartEvent[] => {\n return [\n {\n type: 'ProductItemAdded',\n data: { productItem: command.data.productItem },\n },\n { type: 'DiscountApplied', data: { percent: defaultDiscount } },\n ];\n};\n\nconst handleCommand = CommandHandler<ShoppingCart, ShoppingCartEvent>(\n evolve,\n getInitialState,\n);\n\ndescribe('Command Handler', () => {\n const eventStore = getInMemoryEventStore();\n\n it('When called successfuly returns new state for a single returned event', async () => {\n const productItem: PricedProductItem = {\n productId: '123',\n quantity: 10,\n price: 3,\n };\n\n const shoppingCartId = randomUUID();\n const command: AddProductItem = {\n type: 'AddProductItem',\n data: { productItem },\n };\n\n const { nextExpectedStreamVersion, newState } = await handleCommand(\n eventStore,\n shoppingCartId,\n (state) => addProductItem(command, state),\n );\n\n assert.deepEqual(newState, {\n productItems: [productItem],\n totalAmount: productItem.price * productItem.quantity,\n });\n assert.equal(nextExpectedStreamVersion, 1);\n });\n\n it('When called successfuly returns new state for multiple returned events', async () => {\n const productItem: PricedProductItem = {\n productId: '123',\n quantity: 10,\n price: 3,\n };\n\n const shoppingCartId = randomUUID();\n const command: AddProductItem = {\n type: 'AddProductItem',\n data: { productItem },\n };\n\n const { nextExpectedStreamVersion, newState } = await handleCommand(\n eventStore,\n shoppingCartId,\n (state) => addProductItemWithDiscount(command, state),\n );\n\n assert.deepEqual(newState, {\n productItems: [productItem],\n totalAmount:\n productItem.price * productItem.quantity * (1 - defaultDiscount),\n });\n assert.equal(nextExpectedStreamVersion, 2);\n });\n});\n"],"mappings":"AACA,OAAO,YAAY;AACnB,SAAS,kBAAkB;AAC3B,SAAS,UAAU,UAAU;AAC7B,SAAS,6BAA6B;AACtC,eAA2B;AAC3B,SAAS,sBAAsB;AAmB/B,MAAM,SAAS,CACb,OACA,EAAE,MAAM,KAAK,MACI;AACjB,UAAQ,MAAM;AAAA,IACZ,KAAK,oBAAoB;AACvB,YAAM,cAAc,KAAK;AACzB,aAAO;AAAA,QACL,cAAc,CAAC,GAAG,MAAM,cAAc,WAAW;AAAA,QACjD,aACE,MAAM,cAAc,YAAY,QAAQ,YAAY;AAAA,MACxD;AAAA,IACF;AAAA,IACA,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,aAAa,MAAM,eAAe,IAAI,KAAK;AAAA,MAC7C;AAAA,EACJ;AACF;AAEA,MAAM,kBAAkB,MAAoB;AAC1C,SAAO,EAAE,cAAc,CAAC,GAAG,aAAa,EAAE;AAC5C;AASA,MAAM,iBAAiB,CACrB,SACA,WACsB;AACtB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM,EAAE,aAAa,QAAQ,KAAK,YAAY;AAAA,EAChD;AACF;AAEA,MAAM,kBAAkB;AAExB,MAAM,6BAA6B,CACjC,SACA,WACwB;AACxB,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,MAAM,EAAE,aAAa,QAAQ,KAAK,YAAY;AAAA,IAChD;AAAA,IACA,EAAE,MAAM,mBAAmB,MAAM,EAAE,SAAS,gBAAgB,EAAE;AAAA,EAChE;AACF;AAEA,MAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AACF;AAEA,SAAS,mBAAmB,MAAM;AAChC,QAAM,aAAa,sBAAsB;AAEzC,KAAG,yEAAyE,YAAY;AACtF,UAAM,cAAiC;AAAA,MACrC,WAAW;AAAA,MACX,UAAU;AAAA,MACV,OAAO;AAAA,IACT;AAEA,UAAM,iBAAiB,WAAW;AAClC,UAAM,UAA0B;AAAA,MAC9B,MAAM;AAAA,MACN,MAAM,EAAE,YAAY;AAAA,IACtB;AAEA,UAAM,EAAE,2BAA2B,SAAS,IAAI,MAAM;AAAA,MACpD;AAAA,MACA;AAAA,MACA,CAAC,UAAU,eAAe,SAAS,KAAK;AAAA,IAC1C;AAEA,WAAO,UAAU,UAAU;AAAA,MACzB,cAAc,CAAC,WAAW;AAAA,MAC1B,aAAa,YAAY,QAAQ,YAAY;AAAA,IAC/C,CAAC;AACD,WAAO,MAAM,2BAA2B,CAAC;AAAA,EAC3C,CAAC;AAED,KAAG,0EAA0E,YAAY;AACvF,UAAM,cAAiC;AAAA,MACrC,WAAW;AAAA,MACX,UAAU;AAAA,MACV,OAAO;AAAA,IACT;AAEA,UAAM,iBAAiB,WAAW;AAClC,UAAM,UAA0B;AAAA,MAC9B,MAAM;AAAA,MACN,MAAM,EAAE,YAAY;AAAA,IACtB;AAEA,UAAM,EAAE,2BAA2B,SAAS,IAAI,MAAM;AAAA,MACpD;AAAA,MACA;AAAA,MACA,CAAC,UAAU,2BAA2B,SAAS,KAAK;AAAA,IACtD;AAEA,WAAO,UAAU,UAAU;AAAA,MACzB,cAAc,CAAC,WAAW;AAAA,MAC1B,aACE,YAAY,QAAQ,YAAY,YAAY,IAAI;AAAA,IACpD,CAAC;AACD,WAAO,MAAM,2BAA2B,CAAC;AAAA,EAC3C,CAAC;AACH,CAAC;","names":[]}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CommandHandlerResult } from './handleCommand.mjs';
|
|
2
|
+
import { E as EventStore, e as ExpectedStreamVersion } from '../eventStore-DLezSgsV.mjs';
|
|
2
3
|
import { Command, Event, Decider } from '../typing/index.mjs';
|
|
3
4
|
import '../errors/index.mjs';
|
|
4
5
|
|
|
5
6
|
declare const DeciderCommandHandler: <State, CommandType extends Command, StreamEvent extends Event, StreamVersion = bigint>({ decide, evolve, getInitialState, }: Decider<State, CommandType, StreamEvent>, mapToStreamId?: (id: string) => string) => (eventStore: EventStore<StreamVersion>, id: string, command: CommandType, options?: {
|
|
6
7
|
expectedStreamVersion?: ExpectedStreamVersion<StreamVersion> | undefined;
|
|
7
|
-
} | undefined) => Promise<
|
|
8
|
+
} | undefined) => Promise<CommandHandlerResult<State, StreamVersion>>;
|
|
8
9
|
|
|
9
10
|
export { DeciderCommandHandler };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CommandHandlerResult } from './handleCommand.js';
|
|
2
|
+
import { E as EventStore, e as ExpectedStreamVersion } from '../eventStore-N_YMFCDT.js';
|
|
2
3
|
import { Command, Event, Decider } from '../typing/index.js';
|
|
3
4
|
import '../errors/index.js';
|
|
4
5
|
|
|
5
6
|
declare const DeciderCommandHandler: <State, CommandType extends Command, StreamEvent extends Event, StreamVersion = bigint>({ decide, evolve, getInitialState, }: Decider<State, CommandType, StreamEvent>, mapToStreamId?: (id: string) => string) => (eventStore: EventStore<StreamVersion>, id: string, command: CommandType, options?: {
|
|
6
7
|
expectedStreamVersion?: ExpectedStreamVersion<StreamVersion> | undefined;
|
|
7
|
-
} | undefined) => Promise<
|
|
8
|
+
} | undefined) => Promise<CommandHandlerResult<State, StreamVersion>>;
|
|
8
9
|
|
|
9
10
|
export { DeciderCommandHandler };
|
|
@@ -1,14 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
getInitialState
|
|
6
|
-
}, mapToStreamId = (id) => id) => async (eventStore, id, command, options) => _handleCommand.CommandHandler.call(void 0,
|
|
7
|
-
evolve,
|
|
8
|
-
getInitialState,
|
|
9
|
-
mapToStreamId
|
|
10
|
-
)(eventStore, id, (state) => decide(command, state), options);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
exports.DeciderCommandHandler = DeciderCommandHandler;
|
|
1
|
+
import { CommandHandler } from './handleCommand';
|
|
2
|
+
// #region command-handler
|
|
3
|
+
export const DeciderCommandHandler = ({ decide, evolve, getInitialState, }, mapToStreamId = (id) => id) => async (eventStore, id, command, options) => CommandHandler(evolve, getInitialState, mapToStreamId)(eventStore, id, (state) => decide(command, state), options);
|
|
4
|
+
// #endregion command-handler
|
|
14
5
|
//# sourceMappingURL=handleCommandWithDecider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commandHandling/handleCommandWithDecider.ts"],"names":[],"mappings":"AAOA,
|
|
1
|
+
{"version":3,"file":"handleCommandWithDecider.js","sourceRoot":"","sources":["../../src/commandHandling/handleCommandWithDecider.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,0BAA0B;AAC1B,MAAM,CAAC,MAAM,qBAAqB,GAChC,CAME,EACE,MAAM,EACN,MAAM,EACN,eAAe,GAC0B,EAC3C,gBAAwC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAClD,EAAE,CACJ,KAAK,EACH,UAAqC,EACrC,EAAU,EACV,OAAoB,EACpB,OAEC,EACD,EAAE,CACF,cAAc,CACZ,MAAM,EACN,eAAe,EACf,aAAa,CACd,CAAC,UAAU,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;AAClE,6BAA6B"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { CommandHandler } from './handleCommand.mjs';
|
|
1
|
+
export { CommandHandler, CommandHandlerResult } from './handleCommand.mjs';
|
|
2
2
|
export { DeciderCommandHandler } from './handleCommandWithDecider.mjs';
|
|
3
3
|
import '../eventStore-DLezSgsV.mjs';
|
|
4
4
|
import '../typing/index.mjs';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export * from './handleCommand';
|
|
2
|
+
export * from './handleCommandWithDecider';
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commandHandling/index.ts"],"names":[],"mappings":"AAAA,cAAc;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commandHandling/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC"}
|
package/dist/errors/index.js
CHANGED
|
@@ -1,57 +1,73 @@
|
|
|
1
|
-
|
|
2
|
-
class EmmettError extends Error {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { isNumber, isString } from '../validation';
|
|
2
|
+
export class EmmettError extends Error {
|
|
3
|
+
errorCode;
|
|
4
|
+
constructor(options) {
|
|
5
|
+
const errorCode = options && typeof options === 'object' && 'errorCode' in options
|
|
6
|
+
? options.errorCode
|
|
7
|
+
: isNumber(options)
|
|
8
|
+
? options
|
|
9
|
+
: 500;
|
|
10
|
+
const message = options && typeof options === 'object' && 'message' in options
|
|
11
|
+
? options.message
|
|
12
|
+
: isString(options)
|
|
13
|
+
? options
|
|
14
|
+
: `Error with status code '${errorCode}' ocurred during Emmett processing`;
|
|
15
|
+
super(message);
|
|
16
|
+
this.errorCode = errorCode;
|
|
17
|
+
// 👇️ because we are extending a built-in class
|
|
18
|
+
Object.setPrototypeOf(this, EmmettError.prototype);
|
|
19
|
+
}
|
|
11
20
|
}
|
|
12
|
-
class ConcurrencyError extends EmmettError {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
export class ConcurrencyError extends EmmettError {
|
|
22
|
+
current;
|
|
23
|
+
expected;
|
|
24
|
+
constructor(current, expected, message) {
|
|
25
|
+
super({
|
|
26
|
+
errorCode: 412,
|
|
27
|
+
message: message ??
|
|
28
|
+
`Expected version ${expected.toString()} does not match current ${current?.toString()}`,
|
|
29
|
+
});
|
|
30
|
+
this.current = current;
|
|
31
|
+
this.expected = expected;
|
|
32
|
+
// 👇️ because we are extending a built-in class
|
|
33
|
+
Object.setPrototypeOf(this, ConcurrencyError.prototype);
|
|
34
|
+
}
|
|
22
35
|
}
|
|
23
|
-
class ValidationError extends EmmettError {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
export class ValidationError extends EmmettError {
|
|
37
|
+
constructor(message) {
|
|
38
|
+
super({
|
|
39
|
+
errorCode: 400,
|
|
40
|
+
message: message ?? `Validation Error ocurred during Emmett processing`,
|
|
41
|
+
});
|
|
42
|
+
// 👇️ because we are extending a built-in class
|
|
43
|
+
Object.setPrototypeOf(this, ValidationError.prototype);
|
|
44
|
+
}
|
|
31
45
|
}
|
|
32
|
-
class IllegalStateError extends EmmettError {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
export class IllegalStateError extends EmmettError {
|
|
47
|
+
constructor(message) {
|
|
48
|
+
super({
|
|
49
|
+
errorCode: 403,
|
|
50
|
+
message: message ?? `Illegal State ocurred during Emmett processing`,
|
|
51
|
+
});
|
|
52
|
+
// 👇️ because we are extending a built-in class
|
|
53
|
+
Object.setPrototypeOf(this, IllegalStateError.prototype);
|
|
54
|
+
}
|
|
40
55
|
}
|
|
41
|
-
class NotFoundError extends EmmettError {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
56
|
+
export class NotFoundError extends EmmettError {
|
|
57
|
+
constructor(options) {
|
|
58
|
+
super({
|
|
59
|
+
errorCode: 404,
|
|
60
|
+
message: options?.message ??
|
|
61
|
+
(options?.id
|
|
62
|
+
? options.type
|
|
63
|
+
? `${options.type} with ${options.id} was not found during Emmett processing`
|
|
64
|
+
: `State with ${options.id} was not found during Emmett processing`
|
|
65
|
+
: options?.type
|
|
66
|
+
? `${options.type} was not found during Emmett processing`
|
|
67
|
+
: 'State was not found during Emmett processing'),
|
|
68
|
+
});
|
|
69
|
+
// 👇️ because we are extending a built-in class
|
|
70
|
+
Object.setPrototypeOf(this, NotFoundError.prototype);
|
|
71
|
+
}
|
|
49
72
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
exports.ConcurrencyError = ConcurrencyError; exports.EmmettError = EmmettError; exports.IllegalStateError = IllegalStateError; exports.NotFoundError = NotFoundError; exports.ValidationError = ValidationError;
|
|
57
73
|
//# sourceMappingURL=index.js.map
|
package/dist/errors/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC7B,SAAS,CAAS;IAEzB,YACE,OAAmE;QAEnE,MAAM,SAAS,GACb,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,WAAW,IAAI,OAAO;YAC9D,CAAC,CAAC,OAAO,CAAC,SAAS;YACnB,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACjB,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,GAAG,CAAC;QACZ,MAAM,OAAO,GACX,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,SAAS,IAAI,OAAO;YAC5D,CAAC,CAAC,OAAO,CAAC,OAAO;YACjB,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACjB,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,2BAA2B,SAAS,oCAAoC,CAAC;QAEjF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAE3B,gDAAgD;QAChD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,WAAW;IAEtC;IACA;IAFT,YACS,OAA2B,EAC3B,QAAgB,EACvB,OAAgB;QAEhB,KAAK,CAAC;YACJ,SAAS,EAAE,GAAG;YACd,OAAO,EACL,OAAO;gBACP,oBAAoB,QAAQ,CAAC,QAAQ,EAAE,2BAA2B,OAAO,EAAE,QAAQ,EAAE,EAAE;SAC1F,CAAC,CAAC;QATI,YAAO,GAAP,OAAO,CAAoB;QAC3B,aAAQ,GAAR,QAAQ,CAAQ;QAUvB,gDAAgD;QAChD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,WAAW;IAC9C,YAAY,OAAgB;QAC1B,KAAK,CAAC;YACJ,SAAS,EAAE,GAAG;YACd,OAAO,EAAE,OAAO,IAAI,mDAAmD;SACxE,CAAC,CAAC;QAEH,gDAAgD;QAChD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;IACzD,CAAC;CACF;AAED,MAAM,OAAO,iBAAkB,SAAQ,WAAW;IAChD,YAAY,OAAgB;QAC1B,KAAK,CAAC;YACJ,SAAS,EAAE,GAAG;YACd,OAAO,EAAE,OAAO,IAAI,gDAAgD;SACrE,CAAC,CAAC;QAEH,gDAAgD;QAChD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC3D,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,WAAW;IAC5C,YAAY,OAAwD;QAClE,KAAK,CAAC;YACJ,SAAS,EAAE,GAAG;YACd,OAAO,EACL,OAAO,EAAE,OAAO;gBAChB,CAAC,OAAO,EAAE,EAAE;oBACV,CAAC,CAAC,OAAO,CAAC,IAAI;wBACZ,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,SAAS,OAAO,CAAC,EAAE,yCAAyC;wBAC7E,CAAC,CAAC,cAAc,OAAO,CAAC,EAAE,yCAAyC;oBACrE,CAAC,CAAC,OAAO,EAAE,IAAI;wBACb,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,yCAAyC;wBAC1D,CAAC,CAAC,8CAA8C,CAAC;SACxD,CAAC,CAAC;QAEH,gDAAgD;QAChD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACvD,CAAC;CACF"}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=eventStore.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"eventStore.js","sourceRoot":"","sources":["../../src/eventStore/eventStore.ts"],"names":[],"mappings":""}
|