node-cqrs 1.0.0-rc.38 → 1.0.0-rc.39
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/CHANGELOG.md +8 -0
- package/dist/cjs/AggregateCommandHandler.js +23 -3
- package/dist/cjs/AggregateCommandHandler.js.map +1 -1
- package/dist/cjs/EventStore.js +5 -2
- package/dist/cjs/EventStore.js.map +1 -1
- package/dist/cjs/in-memory/InMemoryEventStorage.js +14 -8
- package/dist/cjs/in-memory/InMemoryEventStorage.js.map +1 -1
- package/dist/cjs/interfaces/IEventStorageWriter.js.map +1 -1
- package/dist/cjs/interfaces/isObject.js.map +1 -1
- package/dist/cjs/utils/assert.js +10 -0
- package/dist/cjs/utils/assert.js.map +1 -1
- package/dist/esm/AggregateCommandHandler.js +24 -4
- package/dist/esm/AggregateCommandHandler.js.map +1 -1
- package/dist/esm/EventStore.js +5 -2
- package/dist/esm/EventStore.js.map +1 -1
- package/dist/esm/in-memory/InMemoryEventStorage.js +14 -8
- package/dist/esm/in-memory/InMemoryEventStorage.js.map +1 -1
- package/dist/esm/interfaces/IEventStorageWriter.js.map +1 -1
- package/dist/esm/interfaces/isObject.js.map +1 -1
- package/dist/esm/utils/assert.js +8 -0
- package/dist/esm/utils/assert.js.map +1 -1
- package/package.json +1 -1
- package/src/AggregateCommandHandler.ts +41 -11
- package/src/EventStore.ts +5 -2
- package/src/in-memory/InMemoryEventStorage.ts +19 -10
- package/src/interfaces/IAggregate.ts +19 -2
- package/src/interfaces/IEventStorageWriter.ts +5 -1
- package/src/interfaces/isObject.ts +1 -1
- package/src/utils/assert.ts +10 -0
- package/types/AggregateCommandHandler.d.ts +2 -4
- package/types/EventStore.d.ts +1 -1
- package/types/in-memory/InMemoryEventStorage.d.ts +5 -3
- package/types/interfaces/IAggregate.d.ts +11 -2
- package/types/interfaces/IEventStorageWriter.d.ts +4 -1
- package/types/interfaces/isObject.d.ts +1 -1
- package/types/utils/assert.d.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
# [1.0.0-rc.39](https://github.com/snatalenko/node-cqrs/compare/v1.0.0-rc.38...v1.0.0-rc.39) (2026-02-26)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Changes
|
|
5
|
+
|
|
6
|
+
* Add an option for ES concurrency errors ignoring ([5189ba0](https://github.com/snatalenko/node-cqrs/commit/5189ba05c6fb0c5f8635251062acf76d032da8b0))
|
|
7
|
+
|
|
8
|
+
|
|
1
9
|
# [1.0.0-rc.38](https://github.com/snatalenko/node-cqrs/compare/v1.0.0-rc.37...v1.0.0-rc.38) (2026-02-24)
|
|
2
10
|
|
|
3
11
|
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AggregateCommandHandler = void 0;
|
|
4
4
|
const index_ts_1 = require("./utils/index.js");
|
|
5
5
|
const index_ts_2 = require("./errors/index.js");
|
|
6
|
+
const isObject_ts_1 = require("./interfaces/isObject.js");
|
|
6
7
|
const DEFAULT_MAX_RETRY_ATTEMPTS = 5;
|
|
7
8
|
function normalizeRetryResolver(value) {
|
|
8
9
|
if (typeof value === 'function')
|
|
@@ -10,7 +11,19 @@ function normalizeRetryResolver(value) {
|
|
|
10
11
|
if (value === false)
|
|
11
12
|
return () => false;
|
|
12
13
|
if (typeof value === 'number')
|
|
13
|
-
return (
|
|
14
|
+
return (err, attempt) => err instanceof index_ts_2.ConcurrencyError && attempt < value;
|
|
15
|
+
if ((0, isObject_ts_1.isObject)(value)) {
|
|
16
|
+
const { maxRetries = DEFAULT_MAX_RETRY_ATTEMPTS, ignoreAfterMaxRetries = false } = value;
|
|
17
|
+
(0, index_ts_1.assertNonNegativeInteger)(maxRetries, 'retryOnConcurrencyError.maxRetries');
|
|
18
|
+
(0, index_ts_1.assertBoolean)(ignoreAfterMaxRetries, 'retryOnConcurrencyError.ignoreAfterMaxRetries');
|
|
19
|
+
return (err, attempt) => {
|
|
20
|
+
if (!(err instanceof index_ts_2.ConcurrencyError))
|
|
21
|
+
return false;
|
|
22
|
+
if (attempt < maxRetries)
|
|
23
|
+
return true;
|
|
24
|
+
return ignoreAfterMaxRetries ? 'ignore' : false;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
14
27
|
// undefined or true — default behavior
|
|
15
28
|
return (err, attempt) => err instanceof index_ts_2.ConcurrencyError && attempt < DEFAULT_MAX_RETRY_ATTEMPTS;
|
|
16
29
|
}
|
|
@@ -110,8 +123,9 @@ class AggregateCommandHandler {
|
|
|
110
123
|
const aggregate = aggregateId ?
|
|
111
124
|
await this.#aggregatesCache.get(aggregateId) :
|
|
112
125
|
await this.#createAggregate();
|
|
126
|
+
let events;
|
|
113
127
|
try {
|
|
114
|
-
|
|
128
|
+
events = await aggregate.handle(cmd);
|
|
115
129
|
this.#logger?.info(`${aggregate} "${cmd.type}" command processed, ${events.length} event(s) produced`);
|
|
116
130
|
if (events.length)
|
|
117
131
|
await this.#eventStore.dispatch(events);
|
|
@@ -123,8 +137,14 @@ class AggregateCommandHandler {
|
|
|
123
137
|
// queued on the lock start from a clean state.
|
|
124
138
|
if (aggregateId)
|
|
125
139
|
this.#aggregatesCache.set(aggregateId, this.#restoreAggregate(aggregateId));
|
|
126
|
-
|
|
140
|
+
const retryDecision = this.#shouldRetry(err, attempt);
|
|
141
|
+
if (!retryDecision)
|
|
127
142
|
throw err;
|
|
143
|
+
if (retryDecision === 'ignore' && events?.length) {
|
|
144
|
+
this.#logger?.info(`"${cmd.type}" concurrency error ignored after ${attempt + 1} attempt(s), force-dispatching`);
|
|
145
|
+
await this.#eventStore.dispatch(events, { ignoreConcurrencyError: true });
|
|
146
|
+
return events;
|
|
147
|
+
}
|
|
128
148
|
}
|
|
129
149
|
}
|
|
130
150
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AggregateCommandHandler.js","sourceRoot":"","sources":["../../src/AggregateCommandHandler.ts"],"names":[],"mappings":";;;AAAA,+
|
|
1
|
+
{"version":3,"file":"AggregateCommandHandler.js","sourceRoot":"","sources":["../../src/AggregateCommandHandler.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/EventStore.js
CHANGED
|
@@ -78,9 +78,12 @@ class EventStore {
|
|
|
78
78
|
* @param events - a set of events to commit
|
|
79
79
|
* @returns Signed and committed events
|
|
80
80
|
*/
|
|
81
|
-
async dispatch(events) {
|
|
81
|
+
async dispatch(events, meta) {
|
|
82
82
|
(0, index_ts_2.assertArray)(events, 'events');
|
|
83
|
-
return this.#eventDispatcher.dispatch(events, {
|
|
83
|
+
return this.#eventDispatcher.dispatch(events, {
|
|
84
|
+
origin: 'internal',
|
|
85
|
+
...meta
|
|
86
|
+
});
|
|
84
87
|
}
|
|
85
88
|
on(messageType, handler) {
|
|
86
89
|
this.eventBus.on(messageType, handler);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventStore.js","sourceRoot":"","sources":["../../src/EventStore.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"EventStore.js","sourceRoot":"","sources":["../../src/EventStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,14 +15,16 @@ class InMemoryEventStorage {
|
|
|
15
15
|
this.#nextId += 1;
|
|
16
16
|
return String(this.#nextId);
|
|
17
17
|
}
|
|
18
|
-
async commitEvents(events) {
|
|
18
|
+
async commitEvents(events, options) {
|
|
19
19
|
await (0, index_ts_2.nextCycle)();
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
e.
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
if (!options?.ignoreConcurrencyError) {
|
|
21
|
+
for (const event of events) {
|
|
22
|
+
if (event.aggregateId !== undefined && event.aggregateVersion !== undefined) {
|
|
23
|
+
const conflict = this.#events.find(e => e.aggregateId === event.aggregateId &&
|
|
24
|
+
e.aggregateVersion === event.aggregateVersion);
|
|
25
|
+
if (conflict)
|
|
26
|
+
throw new index_ts_3.ConcurrencyError(`Duplicate aggregateVersion ${event.aggregateVersion} for aggregate ${event.aggregateId}`);
|
|
27
|
+
}
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
30
|
this.#events = this.#events.concat(events);
|
|
@@ -93,7 +95,11 @@ class InMemoryEventStorage {
|
|
|
93
95
|
throw new Error('Event batch does not contain `event`');
|
|
94
96
|
events.push(event);
|
|
95
97
|
}
|
|
96
|
-
|
|
98
|
+
const ignoreConcurrencyError = batch.some(item => item.ignoreConcurrencyError === true);
|
|
99
|
+
if (ignoreConcurrencyError)
|
|
100
|
+
await this.commitEvents(events, { ignoreConcurrencyError: true });
|
|
101
|
+
else
|
|
102
|
+
await this.commitEvents(events);
|
|
97
103
|
return batch;
|
|
98
104
|
}
|
|
99
105
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InMemoryEventStorage.js","sourceRoot":"","sources":["../../../src/in-memory/InMemoryEventStorage.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"InMemoryEventStorage.js","sourceRoot":"","sources":["../../../src/in-memory/InMemoryEventStorage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IEventStorageWriter.js","sourceRoot":"","sources":["../../../src/interfaces/IEventStorageWriter.ts"],"names":[],"mappings":";;;AACA,+CAAyC;
|
|
1
|
+
{"version":3,"file":"IEventStorageWriter.js","sourceRoot":"","sources":["../../../src/interfaces/IEventStorageWriter.ts"],"names":[],"mappings":";;;AACA,+CAAyC;AAelC,MAAM,oBAAoB,GAAG,CAAC,GAAY,EAA8B,EAAE,CAChF,IAAA,sBAAQ,EAAC,GAAG,CAAC;OACV,cAAc,IAAI,GAAG;OACrB,OAAO,GAAG,CAAC,YAAY,KAAK,UAAU,CAAC;AAH9B,QAAA,oBAAoB,wBAGU"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isObject.js","sourceRoot":"","sources":["../../../src/interfaces/isObject.ts"],"names":[],"mappings":";;;AAAO,MAAM,QAAQ,GAAG,CAAC,GAAY,
|
|
1
|
+
{"version":3,"file":"isObject.js","sourceRoot":"","sources":["../../../src/interfaces/isObject.ts"],"names":[],"mappings":";;;AAAO,MAAM,QAAQ,GAAG,CAAC,GAAY,EAA8B,EAAE,CACpE,OAAO,GAAG,KAAK,QAAQ;OACpB,GAAG,KAAK,IAAI;OACZ,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC;OACtB,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AAJX,QAAA,QAAQ,YAIG"}
|
package/dist/cjs/utils/assert.js
CHANGED
|
@@ -12,6 +12,8 @@ exports.assertSnapshotEvent = assertSnapshotEvent;
|
|
|
12
12
|
exports.assertObservable = assertObservable;
|
|
13
13
|
exports.assertNumber = assertNumber;
|
|
14
14
|
exports.assertClass = assertClass;
|
|
15
|
+
exports.assertNonNegativeInteger = assertNonNegativeInteger;
|
|
16
|
+
exports.assertBoolean = assertBoolean;
|
|
15
17
|
const IMessage_ts_1 = require("../interfaces/IMessage.js");
|
|
16
18
|
const IEvent_ts_1 = require("../interfaces/IEvent.js");
|
|
17
19
|
const ISnapshotEvent_ts_1 = require("../interfaces/ISnapshotEvent.js");
|
|
@@ -65,4 +67,12 @@ function assertClass(value, argName) {
|
|
|
65
67
|
if (!(0, isClass_ts_1.isClass)(value))
|
|
66
68
|
throw new TypeError(`${argName} must be a class`);
|
|
67
69
|
}
|
|
70
|
+
function assertNonNegativeInteger(value, argName) {
|
|
71
|
+
if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0)
|
|
72
|
+
throw new TypeError(`${argName} must be a non-negative integer`);
|
|
73
|
+
}
|
|
74
|
+
function assertBoolean(value, argName) {
|
|
75
|
+
if (typeof value !== 'boolean')
|
|
76
|
+
throw new TypeError(`${argName} must be a Boolean`);
|
|
77
|
+
}
|
|
68
78
|
//# sourceMappingURL=assert.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assert.js","sourceRoot":"","sources":["../../../src/utils/assert.ts"],"names":[],"mappings":";;AAMA,sCAGC;AAED,oCAGC;AAED,wCAGC;AAED,oCAGC;AAED,kCAGC;AAED,kDAGC;AAED,sCAGC;AAED,kCAGC;AAED,kDAGC;AAED,4CAGC;AAED,oCAGC;AAED,kCAGC;
|
|
1
|
+
{"version":3,"file":"assert.js","sourceRoot":"","sources":["../../../src/utils/assert.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { assertArray, assertDefined, assertMessage, assertObservable, Lock, MapAssertable } from "./utils/index.js";
|
|
1
|
+
import { assertArray, assertBoolean, assertDefined, assertMessage, assertNonNegativeInteger, assertObservable, Lock, MapAssertable } from "./utils/index.js";
|
|
2
2
|
import { ConcurrencyError } from "./errors/index.js";
|
|
3
|
+
import { isObject } from "./interfaces/isObject.js";
|
|
3
4
|
const DEFAULT_MAX_RETRY_ATTEMPTS = 5;
|
|
4
5
|
function normalizeRetryResolver(value) {
|
|
5
6
|
if (typeof value === 'function')
|
|
@@ -7,7 +8,19 @@ function normalizeRetryResolver(value) {
|
|
|
7
8
|
if (value === false)
|
|
8
9
|
return () => false;
|
|
9
10
|
if (typeof value === 'number')
|
|
10
|
-
return (
|
|
11
|
+
return (err, attempt) => err instanceof ConcurrencyError && attempt < value;
|
|
12
|
+
if (isObject(value)) {
|
|
13
|
+
const { maxRetries = DEFAULT_MAX_RETRY_ATTEMPTS, ignoreAfterMaxRetries = false } = value;
|
|
14
|
+
assertNonNegativeInteger(maxRetries, 'retryOnConcurrencyError.maxRetries');
|
|
15
|
+
assertBoolean(ignoreAfterMaxRetries, 'retryOnConcurrencyError.ignoreAfterMaxRetries');
|
|
16
|
+
return (err, attempt) => {
|
|
17
|
+
if (!(err instanceof ConcurrencyError))
|
|
18
|
+
return false;
|
|
19
|
+
if (attempt < maxRetries)
|
|
20
|
+
return true;
|
|
21
|
+
return ignoreAfterMaxRetries ? 'ignore' : false;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
11
24
|
// undefined or true — default behavior
|
|
12
25
|
return (err, attempt) => err instanceof ConcurrencyError && attempt < DEFAULT_MAX_RETRY_ATTEMPTS;
|
|
13
26
|
}
|
|
@@ -107,8 +120,9 @@ export class AggregateCommandHandler {
|
|
|
107
120
|
const aggregate = aggregateId ?
|
|
108
121
|
await this.#aggregatesCache.get(aggregateId) :
|
|
109
122
|
await this.#createAggregate();
|
|
123
|
+
let events;
|
|
110
124
|
try {
|
|
111
|
-
|
|
125
|
+
events = await aggregate.handle(cmd);
|
|
112
126
|
this.#logger?.info(`${aggregate} "${cmd.type}" command processed, ${events.length} event(s) produced`);
|
|
113
127
|
if (events.length)
|
|
114
128
|
await this.#eventStore.dispatch(events);
|
|
@@ -120,8 +134,14 @@ export class AggregateCommandHandler {
|
|
|
120
134
|
// queued on the lock start from a clean state.
|
|
121
135
|
if (aggregateId)
|
|
122
136
|
this.#aggregatesCache.set(aggregateId, this.#restoreAggregate(aggregateId));
|
|
123
|
-
|
|
137
|
+
const retryDecision = this.#shouldRetry(err, attempt);
|
|
138
|
+
if (!retryDecision)
|
|
124
139
|
throw err;
|
|
140
|
+
if (retryDecision === 'ignore' && events?.length) {
|
|
141
|
+
this.#logger?.info(`"${cmd.type}" concurrency error ignored after ${attempt + 1} attempt(s), force-dispatching`);
|
|
142
|
+
await this.#eventStore.dispatch(events, { ignoreConcurrencyError: true });
|
|
143
|
+
return events;
|
|
144
|
+
}
|
|
125
145
|
}
|
|
126
146
|
}
|
|
127
147
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AggregateCommandHandler.js","sourceRoot":"","sources":["../../src/AggregateCommandHandler.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"AggregateCommandHandler.js","sourceRoot":"","sources":["../../src/AggregateCommandHandler.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/EventStore.js
CHANGED
|
@@ -75,9 +75,12 @@ export class EventStore {
|
|
|
75
75
|
* @param events - a set of events to commit
|
|
76
76
|
* @returns Signed and committed events
|
|
77
77
|
*/
|
|
78
|
-
async dispatch(events) {
|
|
78
|
+
async dispatch(events, meta) {
|
|
79
79
|
assertArray(events, 'events');
|
|
80
|
-
return this.#eventDispatcher.dispatch(events, {
|
|
80
|
+
return this.#eventDispatcher.dispatch(events, {
|
|
81
|
+
origin: 'internal',
|
|
82
|
+
...meta
|
|
83
|
+
});
|
|
81
84
|
}
|
|
82
85
|
on(messageType, handler) {
|
|
83
86
|
this.eventBus.on(messageType, handler);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventStore.js","sourceRoot":"","sources":["../../src/EventStore.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"EventStore.js","sourceRoot":"","sources":["../../src/EventStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,14 +12,16 @@ export class InMemoryEventStorage {
|
|
|
12
12
|
this.#nextId += 1;
|
|
13
13
|
return String(this.#nextId);
|
|
14
14
|
}
|
|
15
|
-
async commitEvents(events) {
|
|
15
|
+
async commitEvents(events, options) {
|
|
16
16
|
await nextCycle();
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
e.
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
if (!options?.ignoreConcurrencyError) {
|
|
18
|
+
for (const event of events) {
|
|
19
|
+
if (event.aggregateId !== undefined && event.aggregateVersion !== undefined) {
|
|
20
|
+
const conflict = this.#events.find(e => e.aggregateId === event.aggregateId &&
|
|
21
|
+
e.aggregateVersion === event.aggregateVersion);
|
|
22
|
+
if (conflict)
|
|
23
|
+
throw new ConcurrencyError(`Duplicate aggregateVersion ${event.aggregateVersion} for aggregate ${event.aggregateId}`);
|
|
24
|
+
}
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
27
|
this.#events = this.#events.concat(events);
|
|
@@ -90,7 +92,11 @@ export class InMemoryEventStorage {
|
|
|
90
92
|
throw new Error('Event batch does not contain `event`');
|
|
91
93
|
events.push(event);
|
|
92
94
|
}
|
|
93
|
-
|
|
95
|
+
const ignoreConcurrencyError = batch.some(item => item.ignoreConcurrencyError === true);
|
|
96
|
+
if (ignoreConcurrencyError)
|
|
97
|
+
await this.commitEvents(events, { ignoreConcurrencyError: true });
|
|
98
|
+
else
|
|
99
|
+
await this.commitEvents(events);
|
|
94
100
|
return batch;
|
|
95
101
|
}
|
|
96
102
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InMemoryEventStorage.js","sourceRoot":"","sources":["../../../src/in-memory/InMemoryEventStorage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"InMemoryEventStorage.js","sourceRoot":"","sources":["../../../src/in-memory/InMemoryEventStorage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IEventStorageWriter.js","sourceRoot":"","sources":["../../../src/interfaces/IEventStorageWriter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"IEventStorageWriter.js","sourceRoot":"","sources":["../../../src/interfaces/IEventStorageWriter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAezC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAY,EAA8B,EAAE,CAChF,QAAQ,CAAC,GAAG,CAAC;OACV,cAAc,IAAI,GAAG;OACrB,OAAO,GAAG,CAAC,YAAY,KAAK,UAAU,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isObject.js","sourceRoot":"","sources":["../../../src/interfaces/isObject.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAY,
|
|
1
|
+
{"version":3,"file":"isObject.js","sourceRoot":"","sources":["../../../src/interfaces/isObject.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAY,EAA8B,EAAE,CACpE,OAAO,GAAG,KAAK,QAAQ;OACpB,GAAG,KAAK,IAAI;OACZ,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC;OACtB,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC"}
|
package/dist/esm/utils/assert.js
CHANGED
|
@@ -51,4 +51,12 @@ export function assertClass(value, argName) {
|
|
|
51
51
|
if (!isClass(value))
|
|
52
52
|
throw new TypeError(`${argName} must be a class`);
|
|
53
53
|
}
|
|
54
|
+
export function assertNonNegativeInteger(value, argName) {
|
|
55
|
+
if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0)
|
|
56
|
+
throw new TypeError(`${argName} must be a non-negative integer`);
|
|
57
|
+
}
|
|
58
|
+
export function assertBoolean(value, argName) {
|
|
59
|
+
if (typeof value !== 'boolean')
|
|
60
|
+
throw new TypeError(`${argName} must be a Boolean`);
|
|
61
|
+
}
|
|
54
62
|
//# sourceMappingURL=assert.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assert.js","sourceRoot":"","sources":["../../../src/utils/assert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAe,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAuB,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAAoB,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,UAAU,aAAa,CAAI,KAAQ,EAAE,OAAe;IACzD,IAAI,CAAC,KAAK;QACT,MAAM,IAAI,SAAS,CAAC,GAAG,OAAO,cAAc,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc,EAAE,OAAe;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,MAAM;QAC7C,MAAM,IAAI,SAAS,CAAC,GAAG,OAAO,6BAA6B,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAc,EAAE,OAAe;IAC7D,IAAI,OAAO,KAAK,KAAK,UAAU;QAC9B,MAAM,IAAI,SAAS,CAAC,GAAG,OAAO,qBAAqB,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc,EAAE,OAAe;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK;QACtC,MAAM,IAAI,SAAS,CAAC,GAAG,OAAO,oBAAoB,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,OAAe;IAC1D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;QACzC,MAAM,IAAI,SAAS,CAAC,GAAG,OAAO,4BAA4B,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAc,EAAE,OAAe;IAClE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACxB,MAAM,IAAI,SAAS,CAAC,GAAG,OAAO,mBAAmB,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc,EAAE,OAAe;IAC5D,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;QACpB,MAAM,IAAI,SAAS,CAAC,GAAG,OAAO,2BAA2B,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,OAAe;IAC1D,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QAClB,MAAM,IAAI,SAAS,CAAC,GAAG,OAAO,yBAAyB,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAc,EAAE,OAAe;IAClE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;QAC1B,MAAM,IAAI,SAAS,CAAC,GAAG,OAAO,iCAAiC,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAc,EAAE,OAAe;IAC/D,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;QACvB,MAAM,IAAI,SAAS,CAAC,GAAG,OAAO,yBAAyB,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc,EAAE,OAAe;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ;QAC5B,MAAM,IAAI,SAAS,CAAC,GAAG,OAAO,mBAAmB,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,OAAe;IAC1D,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QAClB,MAAM,IAAI,SAAS,CAAC,GAAG,OAAO,kBAAkB,CAAC,CAAC;AACpD,CAAC"}
|
|
1
|
+
{"version":3,"file":"assert.js","sourceRoot":"","sources":["../../../src/utils/assert.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
assertArray, assertBoolean, assertDefined, assertMessage, assertNonNegativeInteger, assertObservable,
|
|
3
|
+
Lock, MapAssertable
|
|
4
|
+
} from './utils/index.ts';
|
|
2
5
|
import { ConcurrencyError } from './errors/index.ts';
|
|
3
6
|
import type {
|
|
4
7
|
AggregateEventsQueryParams,
|
|
@@ -13,21 +16,40 @@ import type {
|
|
|
13
16
|
IEventStore,
|
|
14
17
|
ILocker,
|
|
15
18
|
ILogger,
|
|
16
|
-
IObservable
|
|
19
|
+
IObservable,
|
|
20
|
+
RetryOnConcurrencyErrorConfig,
|
|
21
|
+
RetryOnConcurrencyErrorDecision,
|
|
22
|
+
RetryOnConcurrencyErrorResolver
|
|
17
23
|
} from './interfaces/index.ts';
|
|
18
|
-
|
|
24
|
+
import { isObject } from './interfaces/isObject.ts';
|
|
19
25
|
|
|
20
26
|
const DEFAULT_MAX_RETRY_ATTEMPTS = 5;
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
function normalizeRetryResolver(
|
|
29
|
+
value: boolean | number | RetryOnConcurrencyErrorConfig | RetryOnConcurrencyErrorResolver | undefined
|
|
30
|
+
): RetryOnConcurrencyErrorResolver {
|
|
25
31
|
if (typeof value === 'function')
|
|
26
32
|
return value;
|
|
27
33
|
if (value === false)
|
|
28
34
|
return () => false;
|
|
29
35
|
if (typeof value === 'number')
|
|
30
|
-
return (
|
|
36
|
+
return (err, attempt) => err instanceof ConcurrencyError && attempt < value;
|
|
37
|
+
|
|
38
|
+
if (isObject(value)) {
|
|
39
|
+
const { maxRetries = DEFAULT_MAX_RETRY_ATTEMPTS, ignoreAfterMaxRetries = false } = value;
|
|
40
|
+
assertNonNegativeInteger(maxRetries, 'retryOnConcurrencyError.maxRetries');
|
|
41
|
+
assertBoolean(ignoreAfterMaxRetries, 'retryOnConcurrencyError.ignoreAfterMaxRetries');
|
|
42
|
+
|
|
43
|
+
return (err, attempt): RetryOnConcurrencyErrorDecision => {
|
|
44
|
+
if (!(err instanceof ConcurrencyError))
|
|
45
|
+
return false;
|
|
46
|
+
|
|
47
|
+
if (attempt < maxRetries)
|
|
48
|
+
return true;
|
|
49
|
+
|
|
50
|
+
return ignoreAfterMaxRetries ? 'ignore' : false;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
31
53
|
|
|
32
54
|
// undefined or true — default behavior
|
|
33
55
|
return (err, attempt) => err instanceof ConcurrencyError && attempt < DEFAULT_MAX_RETRY_ATTEMPTS;
|
|
@@ -47,7 +69,7 @@ export class AggregateCommandHandler<TAggregate extends IAggregate> implements I
|
|
|
47
69
|
readonly #aggregateFactory: IAggregateFactory<TAggregate, any>;
|
|
48
70
|
readonly #handles: Readonly<string[]>;
|
|
49
71
|
readonly #restoresFrom?: Readonly<string[]>;
|
|
50
|
-
readonly #shouldRetry:
|
|
72
|
+
readonly #shouldRetry: RetryOnConcurrencyErrorResolver;
|
|
51
73
|
|
|
52
74
|
/** Aggregate instances cache for concurrent command handling */
|
|
53
75
|
#aggregatesCache: MapAssertable<Identifier, Promise<TAggregate>> = new MapAssertable();
|
|
@@ -69,7 +91,7 @@ export class AggregateCommandHandler<TAggregate extends IAggregate> implements I
|
|
|
69
91
|
aggregateFactory?: IAggregateFactory<TAggregate, any>,
|
|
70
92
|
handles?: Readonly<string[]>,
|
|
71
93
|
restoresFrom?: Readonly<string[]>,
|
|
72
|
-
retryOnConcurrencyError?: boolean | number |
|
|
94
|
+
retryOnConcurrencyError?: boolean | number | RetryOnConcurrencyErrorConfig | RetryOnConcurrencyErrorResolver
|
|
73
95
|
}) {
|
|
74
96
|
assertDefined(eventStore, 'eventStore');
|
|
75
97
|
|
|
@@ -169,8 +191,9 @@ export class AggregateCommandHandler<TAggregate extends IAggregate> implements I
|
|
|
169
191
|
await this.#aggregatesCache.get(aggregateId)! :
|
|
170
192
|
await this.#createAggregate();
|
|
171
193
|
|
|
194
|
+
let events: IEventSet | undefined;
|
|
172
195
|
try {
|
|
173
|
-
|
|
196
|
+
events = await aggregate.handle(cmd);
|
|
174
197
|
|
|
175
198
|
this.#logger?.info(`${aggregate} "${cmd.type}" command processed, ${events.length} event(s) produced`);
|
|
176
199
|
|
|
@@ -186,8 +209,15 @@ export class AggregateCommandHandler<TAggregate extends IAggregate> implements I
|
|
|
186
209
|
if (aggregateId)
|
|
187
210
|
this.#aggregatesCache.set(aggregateId, this.#restoreAggregate(aggregateId));
|
|
188
211
|
|
|
189
|
-
|
|
212
|
+
const retryDecision = this.#shouldRetry(err, attempt);
|
|
213
|
+
if (!retryDecision)
|
|
190
214
|
throw err;
|
|
215
|
+
|
|
216
|
+
if (retryDecision === 'ignore' && events?.length) {
|
|
217
|
+
this.#logger?.info(`"${cmd.type}" concurrency error ignored after ${attempt + 1} attempt(s), force-dispatching`);
|
|
218
|
+
await this.#eventStore.dispatch(events, { ignoreConcurrencyError: true });
|
|
219
|
+
return events;
|
|
220
|
+
}
|
|
191
221
|
}
|
|
192
222
|
}
|
|
193
223
|
}
|
package/src/EventStore.ts
CHANGED
|
@@ -143,10 +143,13 @@ export class EventStore implements IEventStore {
|
|
|
143
143
|
* @param events - a set of events to commit
|
|
144
144
|
* @returns Signed and committed events
|
|
145
145
|
*/
|
|
146
|
-
async dispatch(events: IEventSet): Promise<IEventSet> {
|
|
146
|
+
async dispatch(events: IEventSet, meta?: Record<string, any>): Promise<IEventSet> {
|
|
147
147
|
assertArray(events, 'events');
|
|
148
148
|
|
|
149
|
-
return this.#eventDispatcher.dispatch(events, {
|
|
149
|
+
return this.#eventDispatcher.dispatch(events, {
|
|
150
|
+
origin: 'internal',
|
|
151
|
+
...meta
|
|
152
|
+
});
|
|
150
153
|
}
|
|
151
154
|
|
|
152
155
|
on(messageType: string, handler: IMessageHandler) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
CommitEventsOptions,
|
|
2
3
|
IIdentifierProvider,
|
|
3
4
|
IEvent,
|
|
4
5
|
IEventSet,
|
|
@@ -8,6 +9,7 @@ import type {
|
|
|
8
9
|
IEventStorageWriter,
|
|
9
10
|
Identifier,
|
|
10
11
|
IDispatchPipelineProcessor,
|
|
12
|
+
DispatchPipelineEnvelope,
|
|
11
13
|
DispatchPipelineBatch,
|
|
12
14
|
AggregateEventsQueryParams
|
|
13
15
|
} from '../interfaces/index.ts';
|
|
@@ -33,16 +35,18 @@ export class InMemoryEventStorage implements
|
|
|
33
35
|
return String(this.#nextId);
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
async commitEvents(events: IEventSet): Promise<IEventSet> {
|
|
38
|
+
async commitEvents(events: IEventSet, options?: CommitEventsOptions): Promise<IEventSet> {
|
|
37
39
|
await nextCycle();
|
|
38
40
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
if (!options?.ignoreConcurrencyError) {
|
|
42
|
+
for (const event of events) {
|
|
43
|
+
if (event.aggregateId !== undefined && event.aggregateVersion !== undefined) {
|
|
44
|
+
const conflict = this.#events.find(e =>
|
|
45
|
+
e.aggregateId === event.aggregateId &&
|
|
46
|
+
e.aggregateVersion === event.aggregateVersion);
|
|
47
|
+
if (conflict)
|
|
48
|
+
throw new ConcurrencyError(`Duplicate aggregateVersion ${event.aggregateVersion} for aggregate ${event.aggregateId}`);
|
|
49
|
+
}
|
|
46
50
|
}
|
|
47
51
|
}
|
|
48
52
|
|
|
@@ -128,7 +132,8 @@ export class InMemoryEventStorage implements
|
|
|
128
132
|
*
|
|
129
133
|
* This method is part of the `IDispatchPipelineProcessor` interface.
|
|
130
134
|
*/
|
|
131
|
-
async process(batch: DispatchPipelineBatch
|
|
135
|
+
async process(batch: DispatchPipelineBatch<DispatchPipelineEnvelope & { ignoreConcurrencyError?: boolean }>):
|
|
136
|
+
Promise<DispatchPipelineBatch> {
|
|
132
137
|
const events: IEvent[] = [];
|
|
133
138
|
for (const { event } of batch) {
|
|
134
139
|
if (!event)
|
|
@@ -137,7 +142,11 @@ export class InMemoryEventStorage implements
|
|
|
137
142
|
events.push(event);
|
|
138
143
|
}
|
|
139
144
|
|
|
140
|
-
|
|
145
|
+
const ignoreConcurrencyError = batch.some(item => item.ignoreConcurrencyError === true);
|
|
146
|
+
if (ignoreConcurrencyError)
|
|
147
|
+
await this.commitEvents(events, { ignoreConcurrencyError: true });
|
|
148
|
+
else
|
|
149
|
+
await this.commitEvents(events);
|
|
141
150
|
|
|
142
151
|
return batch;
|
|
143
152
|
}
|
|
@@ -47,6 +47,16 @@ export type IAggregateConstructorParams<TState extends IMutableState | object |
|
|
|
47
47
|
state?: TState
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
+
export type RetryOnConcurrencyErrorDecision = boolean | 'ignore';
|
|
51
|
+
|
|
52
|
+
export type RetryOnConcurrencyErrorResolver =
|
|
53
|
+
(err: unknown, attempt: number) => RetryOnConcurrencyErrorDecision;
|
|
54
|
+
|
|
55
|
+
export type RetryOnConcurrencyErrorConfig = {
|
|
56
|
+
maxRetries?: number;
|
|
57
|
+
ignoreAfterMaxRetries?: boolean;
|
|
58
|
+
};
|
|
59
|
+
|
|
50
60
|
export interface IAggregateConstructor<
|
|
51
61
|
TAggregate extends IAggregate,
|
|
52
62
|
TState extends IMutableState | object | void
|
|
@@ -74,9 +84,16 @@ export interface IAggregateConstructor<
|
|
|
74
84
|
* - `false`: no retry
|
|
75
85
|
* - `true`: retry up to 5 times on ConcurrencyError
|
|
76
86
|
* - `number`: retry up to the specified number of times
|
|
77
|
-
* - `
|
|
87
|
+
* - `RetryOnConcurrencyErrorConfig`: configure retries (`maxRetries` must be a non-negative integer)
|
|
88
|
+
* and optional ignore on exhaustion
|
|
89
|
+
* - `(err, attempt) => RetryOnConcurrencyErrorDecision`:
|
|
90
|
+
* custom function to decide whether to retry (`true`), stop (`false`) or ignore (`'ignore'`)
|
|
78
91
|
*/
|
|
79
|
-
readonly retryOnConcurrencyError?:
|
|
92
|
+
readonly retryOnConcurrencyError?:
|
|
93
|
+
| boolean
|
|
94
|
+
| number
|
|
95
|
+
| RetryOnConcurrencyErrorConfig
|
|
96
|
+
| RetryOnConcurrencyErrorResolver;
|
|
80
97
|
|
|
81
98
|
new(options: IAggregateConstructorParams<TState>): TAggregate;
|
|
82
99
|
}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import type { IEventSet } from './IEventSet.ts';
|
|
2
2
|
import { isObject } from './isObject.ts';
|
|
3
3
|
|
|
4
|
+
export type CommitEventsOptions = {
|
|
5
|
+
ignoreConcurrencyError?: boolean;
|
|
6
|
+
};
|
|
7
|
+
|
|
4
8
|
export interface IEventStorageWriter {
|
|
5
9
|
|
|
6
10
|
/**
|
|
7
11
|
* Persists a set of events to the event store.
|
|
8
12
|
* Returns the persisted event set (potentially enriched or normalized).
|
|
9
13
|
*/
|
|
10
|
-
commitEvents(events: IEventSet): Promise<IEventSet>;
|
|
14
|
+
commitEvents(events: IEventSet, options?: CommitEventsOptions): Promise<IEventSet>;
|
|
11
15
|
}
|
|
12
16
|
|
|
13
17
|
export const isEventStorageWriter = (obj: unknown): obj is IEventStorageWriter =>
|
package/src/utils/assert.ts
CHANGED
|
@@ -63,3 +63,13 @@ export function assertClass(value: unknown, argName: string): asserts value is n
|
|
|
63
63
|
if (!isClass(value))
|
|
64
64
|
throw new TypeError(`${argName} must be a class`);
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
export function assertNonNegativeInteger(value: unknown, argName: string): asserts value is number {
|
|
68
|
+
if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0)
|
|
69
|
+
throw new TypeError(`${argName} must be a non-negative integer`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function assertBoolean(value: unknown, argName: string): asserts value is boolean {
|
|
73
|
+
if (typeof value !== 'boolean')
|
|
74
|
+
throw new TypeError(`${argName} must be a Boolean`);
|
|
75
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { IAggregate, IAggregateConstructor, IAggregateFactory, ICommand, ICommandHandler, IContainer, IEventSet, IObservable } from './interfaces/index.ts';
|
|
2
|
-
type RetryResolver = (err: unknown, attempt: number) => boolean;
|
|
1
|
+
import type { IAggregate, IAggregateConstructor, IAggregateFactory, ICommand, ICommandHandler, IContainer, IEventSet, IObservable, RetryOnConcurrencyErrorConfig, RetryOnConcurrencyErrorResolver } from './interfaces/index.ts';
|
|
3
2
|
/**
|
|
4
3
|
* Aggregate command handler.
|
|
5
4
|
*
|
|
@@ -14,11 +13,10 @@ export declare class AggregateCommandHandler<TAggregate extends IAggregate> impl
|
|
|
14
13
|
aggregateFactory?: IAggregateFactory<TAggregate, any>;
|
|
15
14
|
handles?: Readonly<string[]>;
|
|
16
15
|
restoresFrom?: Readonly<string[]>;
|
|
17
|
-
retryOnConcurrencyError?: boolean | number |
|
|
16
|
+
retryOnConcurrencyError?: boolean | number | RetryOnConcurrencyErrorConfig | RetryOnConcurrencyErrorResolver;
|
|
18
17
|
});
|
|
19
18
|
/** Subscribe to all command types handled by aggregateType */
|
|
20
19
|
subscribe(commandBus: IObservable): void;
|
|
21
20
|
/** Pass a command to corresponding aggregate */
|
|
22
21
|
execute(cmd: ICommand): Promise<IEventSet>;
|
|
23
22
|
}
|
|
24
|
-
export {};
|
package/types/EventStore.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export declare class EventStore implements IEventStore {
|
|
|
20
20
|
* @param events - a set of events to commit
|
|
21
21
|
* @returns Signed and committed events
|
|
22
22
|
*/
|
|
23
|
-
dispatch(events: IEventSet): Promise<IEventSet>;
|
|
23
|
+
dispatch(events: IEventSet, meta?: Record<string, any>): Promise<IEventSet>;
|
|
24
24
|
on(messageType: string, handler: IMessageHandler): void;
|
|
25
25
|
off(messageType: string, handler: IMessageHandler): void;
|
|
26
26
|
queue(name: string): IObservable;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IIdentifierProvider, IEvent, IEventSet, EventQueryAfter, IEventStorageReader, IEventStream, IEventStorageWriter, Identifier, IDispatchPipelineProcessor, DispatchPipelineBatch, AggregateEventsQueryParams } from '../interfaces/index.ts';
|
|
1
|
+
import type { CommitEventsOptions, IIdentifierProvider, IEvent, IEventSet, EventQueryAfter, IEventStorageReader, IEventStream, IEventStorageWriter, Identifier, IDispatchPipelineProcessor, DispatchPipelineEnvelope, DispatchPipelineBatch, AggregateEventsQueryParams } from '../interfaces/index.ts';
|
|
2
2
|
/**
|
|
3
3
|
* A simple event storage implementation intended to use for tests only.
|
|
4
4
|
* Storage content resets on each app restart.
|
|
@@ -6,7 +6,7 @@ import type { IIdentifierProvider, IEvent, IEventSet, EventQueryAfter, IEventSto
|
|
|
6
6
|
export declare class InMemoryEventStorage implements IEventStorageReader, IEventStorageWriter, IIdentifierProvider, IDispatchPipelineProcessor {
|
|
7
7
|
#private;
|
|
8
8
|
getNewId(): string;
|
|
9
|
-
commitEvents(events: IEventSet): Promise<IEventSet>;
|
|
9
|
+
commitEvents(events: IEventSet, options?: CommitEventsOptions): Promise<IEventSet>;
|
|
10
10
|
getAggregateEvents(aggregateId: Identifier, options?: AggregateEventsQueryParams): IEventStream;
|
|
11
11
|
getSagaEvents(sagaId: Identifier, { beforeEvent }: {
|
|
12
12
|
beforeEvent: IEvent;
|
|
@@ -18,5 +18,7 @@ export declare class InMemoryEventStorage implements IEventStorageReader, IEvent
|
|
|
18
18
|
*
|
|
19
19
|
* This method is part of the `IDispatchPipelineProcessor` interface.
|
|
20
20
|
*/
|
|
21
|
-
process(batch: DispatchPipelineBatch
|
|
21
|
+
process(batch: DispatchPipelineBatch<DispatchPipelineEnvelope & {
|
|
22
|
+
ignoreConcurrencyError?: boolean;
|
|
23
|
+
}>): Promise<DispatchPipelineBatch>;
|
|
22
24
|
}
|
|
@@ -39,6 +39,12 @@ export type IAggregateConstructorParams<TState extends IMutableState | object |
|
|
|
39
39
|
/** Aggregate state instance */
|
|
40
40
|
state?: TState;
|
|
41
41
|
};
|
|
42
|
+
export type RetryOnConcurrencyErrorDecision = boolean | 'ignore';
|
|
43
|
+
export type RetryOnConcurrencyErrorResolver = (err: unknown, attempt: number) => RetryOnConcurrencyErrorDecision;
|
|
44
|
+
export type RetryOnConcurrencyErrorConfig = {
|
|
45
|
+
maxRetries?: number;
|
|
46
|
+
ignoreAfterMaxRetries?: boolean;
|
|
47
|
+
};
|
|
42
48
|
export interface IAggregateConstructor<TAggregate extends IAggregate, TState extends IMutableState | object | void> {
|
|
43
49
|
/**
|
|
44
50
|
* List of command types handled by the aggregate.
|
|
@@ -60,9 +66,12 @@ export interface IAggregateConstructor<TAggregate extends IAggregate, TState ext
|
|
|
60
66
|
* - `false`: no retry
|
|
61
67
|
* - `true`: retry up to 5 times on ConcurrencyError
|
|
62
68
|
* - `number`: retry up to the specified number of times
|
|
63
|
-
* - `
|
|
69
|
+
* - `RetryOnConcurrencyErrorConfig`: configure retries (`maxRetries` must be a non-negative integer)
|
|
70
|
+
* and optional ignore on exhaustion
|
|
71
|
+
* - `(err, attempt) => RetryOnConcurrencyErrorDecision`:
|
|
72
|
+
* custom function to decide whether to retry (`true`), stop (`false`) or ignore (`'ignore'`)
|
|
64
73
|
*/
|
|
65
|
-
readonly retryOnConcurrencyError?: boolean | number |
|
|
74
|
+
readonly retryOnConcurrencyError?: boolean | number | RetryOnConcurrencyErrorConfig | RetryOnConcurrencyErrorResolver;
|
|
66
75
|
new (options: IAggregateConstructorParams<TState>): TAggregate;
|
|
67
76
|
}
|
|
68
77
|
export type IAggregateFactory<TAggregate extends IAggregate, TState extends IMutableState | object | void> = (options: IAggregateConstructorParams<TState>) => TAggregate;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import type { IEventSet } from './IEventSet.ts';
|
|
2
|
+
export type CommitEventsOptions = {
|
|
3
|
+
ignoreConcurrencyError?: boolean;
|
|
4
|
+
};
|
|
2
5
|
export interface IEventStorageWriter {
|
|
3
6
|
/**
|
|
4
7
|
* Persists a set of events to the event store.
|
|
5
8
|
* Returns the persisted event set (potentially enriched or normalized).
|
|
6
9
|
*/
|
|
7
|
-
commitEvents(events: IEventSet): Promise<IEventSet>;
|
|
10
|
+
commitEvents(events: IEventSet, options?: CommitEventsOptions): Promise<IEventSet>;
|
|
8
11
|
}
|
|
9
12
|
export declare const isEventStorageWriter: (obj: unknown) => obj is IEventStorageWriter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const isObject: (obj: unknown) => obj is
|
|
1
|
+
export declare const isObject: (obj: unknown) => obj is Record<string, any>;
|
package/types/utils/assert.d.ts
CHANGED
|
@@ -14,3 +14,5 @@ export declare function assertSnapshotEvent(value: unknown, argName: string): as
|
|
|
14
14
|
export declare function assertObservable(value: unknown, argName: string): asserts value is IObservable;
|
|
15
15
|
export declare function assertNumber(value: unknown, argName: string): asserts value is number;
|
|
16
16
|
export declare function assertClass(value: unknown, argName: string): asserts value is new (...args: any[]) => any;
|
|
17
|
+
export declare function assertNonNegativeInteger(value: unknown, argName: string): asserts value is number;
|
|
18
|
+
export declare function assertBoolean(value: unknown, argName: string): asserts value is boolean;
|