@ocoda/event-sourcing-mariadb 1.0.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/CHANGELOG.md +18 -0
- package/LICENSE.md +21 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.js +716 -0
- package/index.d.ts +1 -0
- package/index.js +17 -0
- package/package.json +58 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# @ocoda/event-sourcing-mariadb
|
|
2
|
+
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- This marks the first stable release of the library, which consists of the following changes:
|
|
8
|
+
|
|
9
|
+
- all database-specific libraries have been migrated to their own libraries to reduce the bundle size
|
|
10
|
+
- the `SnapshotHandler` was renamed to `SnapshotRepository`
|
|
11
|
+
- the `SnapshotRepository` was provided with additional methods for retrieving snapshots in bulk
|
|
12
|
+
- the database drivers were optimized (e.g. by only fetching the needed fields)
|
|
13
|
+
- the DynamoDB snapshot-store serialization was fixed
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @ocoda/event-sourcing@1.0.0
|
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Ocoda
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { IEventPayload, IEvent, EventStore, IEventPool, IEventCollection, EventStream, IEventFilter, EventEnvelope, EventStoreConfig, AggregateRoot, ISnapshot, SnapshotStore, ISnapshotPool, ISnapshotCollection, SnapshotStream, ISnapshotFilter, SnapshotEnvelope, ILatestSnapshotFilter, SnapshotStoreConfig } from '@ocoda/event-sourcing';
|
|
2
|
+
import { Type } from '@nestjs/common';
|
|
3
|
+
import { PoolConfig } from 'mariadb';
|
|
4
|
+
|
|
5
|
+
type MariaDBEventEntity = {
|
|
6
|
+
stream_id: string;
|
|
7
|
+
version: number;
|
|
8
|
+
event: string;
|
|
9
|
+
payload: IEventPayload<IEvent>;
|
|
10
|
+
event_id: string;
|
|
11
|
+
aggregate_id: string;
|
|
12
|
+
occurred_on: Date;
|
|
13
|
+
correlation_id: string | null;
|
|
14
|
+
causation_id: string | null;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
declare class MariaDBEventStore extends EventStore<MariaDBEventStoreConfig> {
|
|
18
|
+
private pool;
|
|
19
|
+
connect(): Promise<void>;
|
|
20
|
+
disconnect(): Promise<void>;
|
|
21
|
+
ensureCollection(pool?: IEventPool): Promise<IEventCollection>;
|
|
22
|
+
getEvents({ streamId }: EventStream, filter?: IEventFilter): AsyncGenerator<IEvent[]>;
|
|
23
|
+
getEvent({ streamId }: EventStream, version: number, pool?: IEventPool): Promise<IEvent>;
|
|
24
|
+
appendEvents(stream: EventStream, aggregateVersion: number, events: IEvent[], pool?: IEventPool): Promise<EventEnvelope[]>;
|
|
25
|
+
getEnvelopes({ streamId }: EventStream, filter?: IEventFilter): AsyncGenerator<EventEnvelope[]>;
|
|
26
|
+
getEnvelope({ streamId }: EventStream, version: number, pool?: IEventPool): Promise<EventEnvelope>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface MariaDBEventStoreConfig extends EventStoreConfig, PoolConfig {
|
|
30
|
+
driver: Type<MariaDBEventStore>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type MariaDBSnapshotEntity<A extends AggregateRoot> = {
|
|
34
|
+
stream_id: string;
|
|
35
|
+
version: number;
|
|
36
|
+
payload: ISnapshot<A>;
|
|
37
|
+
snapshot_id: string;
|
|
38
|
+
aggregate_id: string;
|
|
39
|
+
registered_on: Date;
|
|
40
|
+
aggregate_name: string;
|
|
41
|
+
latest?: string;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
declare class MariaDBSnapshotStore extends SnapshotStore<MariaDBSnapshotStoreConfig> {
|
|
45
|
+
private pool;
|
|
46
|
+
connect(): Promise<void>;
|
|
47
|
+
disconnect(): Promise<void>;
|
|
48
|
+
ensureCollection(pool?: ISnapshotPool): Promise<ISnapshotCollection>;
|
|
49
|
+
stop(): Promise<void>;
|
|
50
|
+
getSnapshots<A extends AggregateRoot>({ streamId }: SnapshotStream, filter?: ISnapshotFilter): AsyncGenerator<ISnapshot<A>[]>;
|
|
51
|
+
getSnapshot<A extends AggregateRoot>({ streamId }: SnapshotStream, version: number, pool?: ISnapshotPool): Promise<ISnapshot<A>>;
|
|
52
|
+
appendSnapshot<A extends AggregateRoot>(stream: SnapshotStream, aggregateVersion: number, snapshot: ISnapshot<A>, pool?: ISnapshotPool): Promise<SnapshotEnvelope<A>>;
|
|
53
|
+
getLastSnapshot<A extends AggregateRoot>(stream: SnapshotStream, pool?: ISnapshotPool): Promise<ISnapshot<A>>;
|
|
54
|
+
getManyLastSnapshots<A extends AggregateRoot>(streams: SnapshotStream[], pool?: ISnapshotPool): Promise<Map<SnapshotStream, ISnapshot<A>>>;
|
|
55
|
+
getLastEnvelope<A extends AggregateRoot>(stream: SnapshotStream, pool?: ISnapshotPool): Promise<SnapshotEnvelope<A>>;
|
|
56
|
+
getEnvelopes<A extends AggregateRoot>({ streamId }: SnapshotStream, filter?: ISnapshotFilter): AsyncGenerator<SnapshotEnvelope<A>[]>;
|
|
57
|
+
getEnvelope<A extends AggregateRoot>({ streamId }: SnapshotStream, version: number, pool?: ISnapshotPool): Promise<SnapshotEnvelope<A>>;
|
|
58
|
+
getLastAggregateEnvelopes<A extends AggregateRoot>(aggregateName: string, filter?: ILatestSnapshotFilter): AsyncGenerator<SnapshotEnvelope<A>[]>;
|
|
59
|
+
getManyLastSnapshotEnvelopes<A extends AggregateRoot>(streams: SnapshotStream[], pool?: ISnapshotPool): Promise<Map<SnapshotStream, SnapshotEnvelope<A>>>;
|
|
60
|
+
private getLastStreamEntities;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface MariaDBSnapshotStoreConfig extends SnapshotStoreConfig, PoolConfig {
|
|
64
|
+
driver: Type<MariaDBSnapshotStore>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export { type MariaDBEventEntity, MariaDBEventStore, type MariaDBEventStoreConfig, type MariaDBSnapshotEntity, MariaDBSnapshotStore, type MariaDBSnapshotStoreConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,716 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
22
|
+
var __async = (__this, __arguments, generator) => {
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
var fulfilled = (value) => {
|
|
25
|
+
try {
|
|
26
|
+
step(generator.next(value));
|
|
27
|
+
} catch (e) {
|
|
28
|
+
reject(e);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
var rejected = (value) => {
|
|
32
|
+
try {
|
|
33
|
+
step(generator.throw(value));
|
|
34
|
+
} catch (e) {
|
|
35
|
+
reject(e);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
39
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
var __await = function(promise, isYieldStar) {
|
|
43
|
+
this[0] = promise;
|
|
44
|
+
this[1] = isYieldStar;
|
|
45
|
+
};
|
|
46
|
+
var __asyncGenerator = (__this, __arguments, generator) => {
|
|
47
|
+
var resume = (k, v, yes, no) => {
|
|
48
|
+
try {
|
|
49
|
+
var x = generator[k](v), isAwait = (v = x.value) instanceof __await, done = x.done;
|
|
50
|
+
Promise.resolve(isAwait ? v[0] : v).then((y) => isAwait ? resume(k === "return" ? k : "next", v[1] ? { done: y.done, value: y.value } : y, yes, no) : yes({ value: y, done })).catch((e) => resume("throw", e, yes, no));
|
|
51
|
+
} catch (e) {
|
|
52
|
+
no(e);
|
|
53
|
+
}
|
|
54
|
+
}, method = (k) => it[k] = (x) => new Promise((yes, no) => resume(k, x, yes, no)), it = {};
|
|
55
|
+
return generator = generator.apply(__this, __arguments), it[__knownSymbol("asyncIterator")] = () => it, method("next"), method("throw"), method("return"), it;
|
|
56
|
+
};
|
|
57
|
+
var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
|
|
58
|
+
|
|
59
|
+
// lib/index.ts
|
|
60
|
+
var lib_exports = {};
|
|
61
|
+
__export(lib_exports, {
|
|
62
|
+
MariaDBEventStore: () => MariaDBEventStore,
|
|
63
|
+
MariaDBSnapshotStore: () => MariaDBSnapshotStore
|
|
64
|
+
});
|
|
65
|
+
module.exports = __toCommonJS(lib_exports);
|
|
66
|
+
|
|
67
|
+
// lib/mariadb.event-store.ts
|
|
68
|
+
var import_event_sourcing = require("@ocoda/event-sourcing");
|
|
69
|
+
var import_mariadb = require("mariadb");
|
|
70
|
+
var _MariaDBEventStore = class _MariaDBEventStore extends import_event_sourcing.EventStore {
|
|
71
|
+
constructor() {
|
|
72
|
+
super(...arguments);
|
|
73
|
+
__publicField(this, "pool");
|
|
74
|
+
}
|
|
75
|
+
connect() {
|
|
76
|
+
return __async(this, null, function* () {
|
|
77
|
+
this.logger.log("Starting store");
|
|
78
|
+
this.pool = (0, import_mariadb.createPool)(this.options);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
disconnect() {
|
|
82
|
+
return __async(this, null, function* () {
|
|
83
|
+
this.logger.log("Stopping store");
|
|
84
|
+
yield this.pool.end();
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
ensureCollection(pool) {
|
|
88
|
+
return __async(this, null, function* () {
|
|
89
|
+
const collection = import_event_sourcing.EventCollection.get(pool);
|
|
90
|
+
try {
|
|
91
|
+
yield this.pool.query(`CREATE TABLE IF NOT EXISTS \`${collection}\` (
|
|
92
|
+
stream_id VARCHAR(120) NOT NULL,
|
|
93
|
+
version INT NOT NULL,
|
|
94
|
+
event VARCHAR(80) NOT NULL,
|
|
95
|
+
payload JSON NOT NULL,
|
|
96
|
+
event_id VARCHAR(40) NOT NULL,
|
|
97
|
+
aggregate_id VARCHAR(40) NOT NULL,
|
|
98
|
+
occurred_on TIMESTAMP NOT NULL,
|
|
99
|
+
correlation_id VARCHAR(255),
|
|
100
|
+
causation_id VARCHAR(255),
|
|
101
|
+
PRIMARY KEY (stream_id, version)
|
|
102
|
+
)`);
|
|
103
|
+
return collection;
|
|
104
|
+
} catch (error) {
|
|
105
|
+
throw new import_event_sourcing.EventStoreCollectionCreationException(collection, error);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
getEvents(_0, _1) {
|
|
110
|
+
return __asyncGenerator(this, arguments, function* ({ streamId }, filter) {
|
|
111
|
+
const connection = this.pool.getConnection();
|
|
112
|
+
const collection = import_event_sourcing.EventCollection.get(filter == null ? void 0 : filter.pool);
|
|
113
|
+
const fromVersion = filter == null ? void 0 : filter.fromVersion;
|
|
114
|
+
const direction = (filter == null ? void 0 : filter.direction) || import_event_sourcing.StreamReadingDirection.FORWARD;
|
|
115
|
+
const limit = (filter == null ? void 0 : filter.limit) || Number.MAX_SAFE_INTEGER;
|
|
116
|
+
const batch = (filter == null ? void 0 : filter.batch) || import_event_sourcing.DEFAULT_BATCH_SIZE;
|
|
117
|
+
const query = `
|
|
118
|
+
SELECT event, payload
|
|
119
|
+
FROM \`${collection}\`
|
|
120
|
+
WHERE stream_id = ?
|
|
121
|
+
${fromVersion ? "AND version >= ?" : ""}
|
|
122
|
+
ORDER BY version ${direction === import_event_sourcing.StreamReadingDirection.FORWARD ? "ASC" : "DESC"}
|
|
123
|
+
LIMIT ?
|
|
124
|
+
`;
|
|
125
|
+
const params = fromVersion ? [
|
|
126
|
+
streamId,
|
|
127
|
+
fromVersion,
|
|
128
|
+
limit
|
|
129
|
+
] : [
|
|
130
|
+
streamId,
|
|
131
|
+
limit
|
|
132
|
+
];
|
|
133
|
+
const client = yield new __await(connection);
|
|
134
|
+
const stream = client.queryStream(query, params);
|
|
135
|
+
try {
|
|
136
|
+
let batchedEvents = [];
|
|
137
|
+
try {
|
|
138
|
+
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
139
|
+
const { event, payload } = temp.value;
|
|
140
|
+
batchedEvents.push(this.eventMap.deserializeEvent(event, payload));
|
|
141
|
+
if (batchedEvents.length === batch) {
|
|
142
|
+
yield batchedEvents;
|
|
143
|
+
batchedEvents = [];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
} catch (temp) {
|
|
147
|
+
error = [temp];
|
|
148
|
+
} finally {
|
|
149
|
+
try {
|
|
150
|
+
more && (temp = iter.return) && (yield new __await(temp.call(iter)));
|
|
151
|
+
} finally {
|
|
152
|
+
if (error)
|
|
153
|
+
throw error[0];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (batchedEvents.length > 0) {
|
|
157
|
+
yield batchedEvents;
|
|
158
|
+
}
|
|
159
|
+
} catch (e) {
|
|
160
|
+
stream.destroy();
|
|
161
|
+
} finally {
|
|
162
|
+
yield new __await(client.release());
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
getEvent(_0, _1, _2) {
|
|
167
|
+
return __async(this, arguments, function* ({ streamId }, version, pool) {
|
|
168
|
+
const collection = import_event_sourcing.EventCollection.get(pool);
|
|
169
|
+
const [entity] = yield this.pool.query(`SELECT event, payload FROM \`${collection}\` WHERE stream_id = ? AND version = ?`, [
|
|
170
|
+
streamId,
|
|
171
|
+
version
|
|
172
|
+
]);
|
|
173
|
+
if (!entity) {
|
|
174
|
+
throw new import_event_sourcing.EventNotFoundException(streamId, version);
|
|
175
|
+
}
|
|
176
|
+
return this.eventMap.deserializeEvent(entity.event, entity.payload);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
appendEvents(stream, aggregateVersion, events, pool) {
|
|
180
|
+
return __async(this, null, function* () {
|
|
181
|
+
const connection = yield this.pool.getConnection();
|
|
182
|
+
const collection = import_event_sourcing.EventCollection.get(pool);
|
|
183
|
+
try {
|
|
184
|
+
const [currentVersionResult] = yield connection.query(`SELECT MAX(version) as version FROM \`${collection}\` WHERE stream_id = ?`, [
|
|
185
|
+
stream.streamId
|
|
186
|
+
]);
|
|
187
|
+
const currentVersion = (currentVersionResult == null ? void 0 : currentVersionResult.version) || 0;
|
|
188
|
+
if (aggregateVersion <= currentVersion) {
|
|
189
|
+
throw new import_event_sourcing.EventStoreVersionConflictException(stream, aggregateVersion, currentVersion);
|
|
190
|
+
}
|
|
191
|
+
let version = aggregateVersion - events.length + 1;
|
|
192
|
+
const envelopes = [];
|
|
193
|
+
for (const event of events) {
|
|
194
|
+
const name = this.eventMap.getName(event);
|
|
195
|
+
const payload = this.eventMap.serializeEvent(event);
|
|
196
|
+
const envelope = import_event_sourcing.EventEnvelope.create(name, payload, {
|
|
197
|
+
aggregateId: stream.aggregateId,
|
|
198
|
+
version: version++
|
|
199
|
+
});
|
|
200
|
+
envelopes.push(envelope);
|
|
201
|
+
}
|
|
202
|
+
yield connection.beginTransaction();
|
|
203
|
+
yield connection.batch(`INSERT INTO \`${collection}\` VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, envelopes.map(({ event, payload, metadata }) => {
|
|
204
|
+
var _a, _b;
|
|
205
|
+
return [
|
|
206
|
+
stream.streamId,
|
|
207
|
+
metadata.version,
|
|
208
|
+
event,
|
|
209
|
+
JSON.stringify(payload),
|
|
210
|
+
metadata.eventId,
|
|
211
|
+
metadata.aggregateId,
|
|
212
|
+
metadata.occurredOn,
|
|
213
|
+
(_a = metadata.correlationId) != null ? _a : null,
|
|
214
|
+
(_b = metadata.causationId) != null ? _b : null
|
|
215
|
+
];
|
|
216
|
+
}));
|
|
217
|
+
yield connection.commit();
|
|
218
|
+
return envelopes;
|
|
219
|
+
} catch (error) {
|
|
220
|
+
yield connection.rollback();
|
|
221
|
+
switch (error.constructor) {
|
|
222
|
+
case import_event_sourcing.EventStoreVersionConflictException:
|
|
223
|
+
throw error;
|
|
224
|
+
default:
|
|
225
|
+
throw new import_event_sourcing.EventStorePersistenceException(collection, error);
|
|
226
|
+
}
|
|
227
|
+
} finally {
|
|
228
|
+
connection.release();
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
getEnvelopes(_0, _1) {
|
|
233
|
+
return __asyncGenerator(this, arguments, function* ({ streamId }, filter) {
|
|
234
|
+
const connection = this.pool.getConnection();
|
|
235
|
+
const collection = import_event_sourcing.EventCollection.get(filter == null ? void 0 : filter.pool);
|
|
236
|
+
const fromVersion = filter == null ? void 0 : filter.fromVersion;
|
|
237
|
+
const direction = (filter == null ? void 0 : filter.direction) || import_event_sourcing.StreamReadingDirection.FORWARD;
|
|
238
|
+
const limit = (filter == null ? void 0 : filter.limit) || Number.MAX_SAFE_INTEGER;
|
|
239
|
+
const batch = (filter == null ? void 0 : filter.batch) || import_event_sourcing.DEFAULT_BATCH_SIZE;
|
|
240
|
+
const query = `
|
|
241
|
+
SELECT event, payload, event_id, aggregate_id, version, occurred_on, correlation_id, causation_id
|
|
242
|
+
FROM \`${collection}\`
|
|
243
|
+
WHERE stream_id = ?
|
|
244
|
+
${fromVersion ? "AND version >= ?" : ""}
|
|
245
|
+
ORDER BY version ${direction === import_event_sourcing.StreamReadingDirection.FORWARD ? "ASC" : "DESC"}
|
|
246
|
+
LIMIT ?
|
|
247
|
+
`;
|
|
248
|
+
const params = fromVersion ? [
|
|
249
|
+
streamId,
|
|
250
|
+
fromVersion,
|
|
251
|
+
limit
|
|
252
|
+
] : [
|
|
253
|
+
streamId,
|
|
254
|
+
limit
|
|
255
|
+
];
|
|
256
|
+
const client = yield new __await(connection);
|
|
257
|
+
const stream = client.queryStream(query, params);
|
|
258
|
+
try {
|
|
259
|
+
let batchedEvents = [];
|
|
260
|
+
try {
|
|
261
|
+
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
262
|
+
const { event, payload, event_id, aggregate_id, version, occurred_on, correlation_id, causation_id } = temp.value;
|
|
263
|
+
batchedEvents.push(import_event_sourcing.EventEnvelope.from(event, payload, {
|
|
264
|
+
eventId: event_id,
|
|
265
|
+
aggregateId: aggregate_id,
|
|
266
|
+
version,
|
|
267
|
+
occurredOn: occurred_on,
|
|
268
|
+
correlationId: correlation_id,
|
|
269
|
+
causationId: causation_id
|
|
270
|
+
}));
|
|
271
|
+
if (batchedEvents.length === batch) {
|
|
272
|
+
yield batchedEvents;
|
|
273
|
+
batchedEvents = [];
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
} catch (temp) {
|
|
277
|
+
error = [temp];
|
|
278
|
+
} finally {
|
|
279
|
+
try {
|
|
280
|
+
more && (temp = iter.return) && (yield new __await(temp.call(iter)));
|
|
281
|
+
} finally {
|
|
282
|
+
if (error)
|
|
283
|
+
throw error[0];
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (batchedEvents.length > 0) {
|
|
287
|
+
yield batchedEvents;
|
|
288
|
+
}
|
|
289
|
+
} catch (e) {
|
|
290
|
+
stream.destroy();
|
|
291
|
+
} finally {
|
|
292
|
+
yield new __await(client.release());
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
getEnvelope(_0, _1, _2) {
|
|
297
|
+
return __async(this, arguments, function* ({ streamId }, version, pool) {
|
|
298
|
+
const collection = import_event_sourcing.EventCollection.get(pool);
|
|
299
|
+
const [entity] = yield this.pool.query(`SELECT event, payload, event_id, aggregate_id, version, occurred_on, correlation_id, causation_id FROM \`${collection}\` WHERE stream_id = ? AND version = ?`, [
|
|
300
|
+
streamId,
|
|
301
|
+
version
|
|
302
|
+
]);
|
|
303
|
+
if (!entity) {
|
|
304
|
+
throw new import_event_sourcing.EventNotFoundException(streamId, version);
|
|
305
|
+
}
|
|
306
|
+
return import_event_sourcing.EventEnvelope.from(entity.event, entity.payload, {
|
|
307
|
+
eventId: entity.event_id,
|
|
308
|
+
aggregateId: entity.aggregate_id,
|
|
309
|
+
version: entity.version,
|
|
310
|
+
occurredOn: entity.occurred_on,
|
|
311
|
+
correlationId: entity.correlation_id,
|
|
312
|
+
causationId: entity.causation_id
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
__name(_MariaDBEventStore, "MariaDBEventStore");
|
|
318
|
+
var MariaDBEventStore = _MariaDBEventStore;
|
|
319
|
+
|
|
320
|
+
// lib/mariadb.snapshot-store.ts
|
|
321
|
+
var import_event_sourcing2 = require("@ocoda/event-sourcing");
|
|
322
|
+
var import_mariadb2 = require("mariadb");
|
|
323
|
+
var _MariaDBSnapshotStore = class _MariaDBSnapshotStore extends import_event_sourcing2.SnapshotStore {
|
|
324
|
+
constructor() {
|
|
325
|
+
super(...arguments);
|
|
326
|
+
__publicField(this, "pool");
|
|
327
|
+
}
|
|
328
|
+
connect() {
|
|
329
|
+
return __async(this, null, function* () {
|
|
330
|
+
this.logger.log("Starting store");
|
|
331
|
+
this.pool = (0, import_mariadb2.createPool)(this.options);
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
disconnect() {
|
|
335
|
+
return __async(this, null, function* () {
|
|
336
|
+
this.logger.log("Stopping store");
|
|
337
|
+
yield this.pool.end();
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
ensureCollection(pool) {
|
|
341
|
+
return __async(this, null, function* () {
|
|
342
|
+
const collection = import_event_sourcing2.SnapshotCollection.get(pool);
|
|
343
|
+
try {
|
|
344
|
+
yield this.pool.query(`CREATE TABLE IF NOT EXISTS \`${collection}\` (
|
|
345
|
+
stream_id VARCHAR(90) NOT NULL,
|
|
346
|
+
version INT NOT NULL,
|
|
347
|
+
payload JSON NOT NULL,
|
|
348
|
+
snapshot_id VARCHAR(40) NOT NULL,
|
|
349
|
+
aggregate_id VARCHAR(40) NOT NULL,
|
|
350
|
+
registered_on TIMESTAMP NOT NULL,
|
|
351
|
+
aggregate_name VARCHAR(50) NOT NULL,
|
|
352
|
+
latest VARCHAR(100),
|
|
353
|
+
PRIMARY KEY (stream_id, version),
|
|
354
|
+
INDEX idx_aggregate_name_latest (aggregate_name, latest)
|
|
355
|
+
)`);
|
|
356
|
+
return collection;
|
|
357
|
+
} catch (error) {
|
|
358
|
+
throw new import_event_sourcing2.SnapshotStoreCollectionCreationException(collection, error);
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
stop() {
|
|
363
|
+
return __async(this, null, function* () {
|
|
364
|
+
this.logger.log("Stopping store");
|
|
365
|
+
yield this.pool.end();
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
getSnapshots(_0, _1) {
|
|
369
|
+
return __asyncGenerator(this, arguments, function* ({ streamId }, filter) {
|
|
370
|
+
const connection = this.pool.getConnection();
|
|
371
|
+
const collection = import_event_sourcing2.SnapshotCollection.get(filter == null ? void 0 : filter.pool);
|
|
372
|
+
const fromVersion = filter == null ? void 0 : filter.fromVersion;
|
|
373
|
+
const direction = (filter == null ? void 0 : filter.direction) || import_event_sourcing2.StreamReadingDirection.FORWARD;
|
|
374
|
+
const limit = (filter == null ? void 0 : filter.limit) || Number.MAX_SAFE_INTEGER;
|
|
375
|
+
const batch = (filter == null ? void 0 : filter.batch) || import_event_sourcing2.DEFAULT_BATCH_SIZE;
|
|
376
|
+
const query = `
|
|
377
|
+
SELECT payload
|
|
378
|
+
FROM \`${collection}\`
|
|
379
|
+
WHERE stream_id = ?
|
|
380
|
+
${fromVersion ? "AND version >= ?" : ""}
|
|
381
|
+
ORDER BY version ${direction === import_event_sourcing2.StreamReadingDirection.FORWARD ? "ASC" : "DESC"}
|
|
382
|
+
LIMIT ?
|
|
383
|
+
`;
|
|
384
|
+
const params = fromVersion ? [
|
|
385
|
+
streamId,
|
|
386
|
+
fromVersion,
|
|
387
|
+
limit
|
|
388
|
+
] : [
|
|
389
|
+
streamId,
|
|
390
|
+
limit
|
|
391
|
+
];
|
|
392
|
+
const client = yield new __await(connection);
|
|
393
|
+
const stream = client.queryStream(query, params);
|
|
394
|
+
try {
|
|
395
|
+
let batchedEvents = [];
|
|
396
|
+
try {
|
|
397
|
+
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
398
|
+
const { payload } = temp.value;
|
|
399
|
+
batchedEvents.push(payload);
|
|
400
|
+
if (batchedEvents.length === batch) {
|
|
401
|
+
yield batchedEvents;
|
|
402
|
+
batchedEvents = [];
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
} catch (temp) {
|
|
406
|
+
error = [temp];
|
|
407
|
+
} finally {
|
|
408
|
+
try {
|
|
409
|
+
more && (temp = iter.return) && (yield new __await(temp.call(iter)));
|
|
410
|
+
} finally {
|
|
411
|
+
if (error)
|
|
412
|
+
throw error[0];
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
if (batchedEvents.length > 0) {
|
|
416
|
+
yield batchedEvents;
|
|
417
|
+
}
|
|
418
|
+
} catch (e) {
|
|
419
|
+
stream.destroy();
|
|
420
|
+
} finally {
|
|
421
|
+
yield new __await(client.release());
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
getSnapshot(_0, _1, _2) {
|
|
426
|
+
return __async(this, arguments, function* ({ streamId }, version, pool) {
|
|
427
|
+
const collection = import_event_sourcing2.SnapshotCollection.get(pool);
|
|
428
|
+
const [entity] = yield this.pool.query(`SELECT payload FROM \`${collection}\` WHERE stream_id = ? AND version = ?`, [
|
|
429
|
+
streamId,
|
|
430
|
+
version
|
|
431
|
+
]);
|
|
432
|
+
if (!entity) {
|
|
433
|
+
throw new import_event_sourcing2.SnapshotNotFoundException(streamId, version);
|
|
434
|
+
}
|
|
435
|
+
return entity.payload;
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
appendSnapshot(stream, aggregateVersion, snapshot, pool) {
|
|
439
|
+
return __async(this, null, function* () {
|
|
440
|
+
const connection = yield this.pool.getConnection();
|
|
441
|
+
const collection = import_event_sourcing2.SnapshotCollection.get(pool);
|
|
442
|
+
try {
|
|
443
|
+
const envelope = import_event_sourcing2.SnapshotEnvelope.create(snapshot, {
|
|
444
|
+
aggregateId: stream.aggregateId,
|
|
445
|
+
version: aggregateVersion
|
|
446
|
+
});
|
|
447
|
+
const [lastStreamEntity] = yield this.getLastStreamEntities(collection, [
|
|
448
|
+
stream
|
|
449
|
+
], [
|
|
450
|
+
"stream_id",
|
|
451
|
+
"version"
|
|
452
|
+
], connection);
|
|
453
|
+
if (aggregateVersion <= (lastStreamEntity == null ? void 0 : lastStreamEntity.version)) {
|
|
454
|
+
throw new import_event_sourcing2.SnapshotStoreVersionConflictException(stream, aggregateVersion, lastStreamEntity.version);
|
|
455
|
+
}
|
|
456
|
+
yield connection.beginTransaction();
|
|
457
|
+
if (lastStreamEntity) {
|
|
458
|
+
yield connection.query(`UPDATE \`${collection}\` SET latest = null WHERE stream_id = ? AND version = ?`, [
|
|
459
|
+
lastStreamEntity.stream_id,
|
|
460
|
+
lastStreamEntity.version
|
|
461
|
+
]);
|
|
462
|
+
}
|
|
463
|
+
yield connection.query(`INSERT INTO \`${collection}\` VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
464
|
+
stream.streamId,
|
|
465
|
+
envelope.metadata.version,
|
|
466
|
+
JSON.stringify(envelope.payload),
|
|
467
|
+
envelope.metadata.snapshotId,
|
|
468
|
+
envelope.metadata.aggregateId,
|
|
469
|
+
envelope.metadata.registeredOn,
|
|
470
|
+
stream.aggregate,
|
|
471
|
+
`latest#${stream.streamId}`
|
|
472
|
+
]);
|
|
473
|
+
yield connection.commit();
|
|
474
|
+
return envelope;
|
|
475
|
+
} catch (error) {
|
|
476
|
+
yield connection.rollback();
|
|
477
|
+
switch (error.constructor) {
|
|
478
|
+
case import_event_sourcing2.SnapshotStoreVersionConflictException:
|
|
479
|
+
throw error;
|
|
480
|
+
default:
|
|
481
|
+
throw new import_event_sourcing2.SnapshotStorePersistenceException(collection, error);
|
|
482
|
+
}
|
|
483
|
+
} finally {
|
|
484
|
+
connection.release();
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
getLastSnapshot(stream, pool) {
|
|
489
|
+
return __async(this, null, function* () {
|
|
490
|
+
const collection = import_event_sourcing2.SnapshotCollection.get(pool);
|
|
491
|
+
const [entity] = yield this.getLastStreamEntities(collection, [
|
|
492
|
+
stream
|
|
493
|
+
], [
|
|
494
|
+
"payload"
|
|
495
|
+
]);
|
|
496
|
+
if (entity) {
|
|
497
|
+
return entity.payload;
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
getManyLastSnapshots(streams, pool) {
|
|
502
|
+
return __async(this, null, function* () {
|
|
503
|
+
const collection = import_event_sourcing2.SnapshotCollection.get(pool);
|
|
504
|
+
const entities = yield this.getLastStreamEntities(collection, streams, [
|
|
505
|
+
"stream_id",
|
|
506
|
+
"payload"
|
|
507
|
+
]);
|
|
508
|
+
return new Map(entities.map(({ stream_id, payload }) => [
|
|
509
|
+
streams.find(({ streamId: currentStreamId }) => currentStreamId === stream_id),
|
|
510
|
+
payload
|
|
511
|
+
]));
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
getLastEnvelope(stream, pool) {
|
|
515
|
+
return __async(this, null, function* () {
|
|
516
|
+
const collection = import_event_sourcing2.SnapshotCollection.get(pool);
|
|
517
|
+
const [entity] = yield this.getLastStreamEntities(collection, [
|
|
518
|
+
stream
|
|
519
|
+
], [
|
|
520
|
+
"payload",
|
|
521
|
+
"snapshot_id",
|
|
522
|
+
"aggregate_id",
|
|
523
|
+
"registered_on",
|
|
524
|
+
"version"
|
|
525
|
+
]);
|
|
526
|
+
if (entity) {
|
|
527
|
+
return import_event_sourcing2.SnapshotEnvelope.from(entity.payload, {
|
|
528
|
+
snapshotId: entity.snapshot_id,
|
|
529
|
+
aggregateId: entity.aggregate_id,
|
|
530
|
+
registeredOn: entity.registered_on,
|
|
531
|
+
version: entity.version
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
getEnvelopes(_0, _1) {
|
|
537
|
+
return __asyncGenerator(this, arguments, function* ({ streamId }, filter) {
|
|
538
|
+
const connection = this.pool.getConnection();
|
|
539
|
+
const collection = import_event_sourcing2.SnapshotCollection.get(filter == null ? void 0 : filter.pool);
|
|
540
|
+
const fromVersion = filter == null ? void 0 : filter.fromVersion;
|
|
541
|
+
const direction = (filter == null ? void 0 : filter.direction) || import_event_sourcing2.StreamReadingDirection.FORWARD;
|
|
542
|
+
const limit = (filter == null ? void 0 : filter.limit) || Number.MAX_SAFE_INTEGER;
|
|
543
|
+
const batch = (filter == null ? void 0 : filter.batch) || import_event_sourcing2.DEFAULT_BATCH_SIZE;
|
|
544
|
+
const query = `
|
|
545
|
+
SELECT payload, aggregate_id, registered_on, snapshot_id, version
|
|
546
|
+
FROM \`${collection}\`
|
|
547
|
+
WHERE stream_id = ?
|
|
548
|
+
${fromVersion ? "AND version >= ?" : ""}
|
|
549
|
+
ORDER BY version ${direction === import_event_sourcing2.StreamReadingDirection.FORWARD ? "ASC" : "DESC"}
|
|
550
|
+
LIMIT ?
|
|
551
|
+
`;
|
|
552
|
+
const params = fromVersion ? [
|
|
553
|
+
streamId,
|
|
554
|
+
fromVersion,
|
|
555
|
+
limit
|
|
556
|
+
] : [
|
|
557
|
+
streamId,
|
|
558
|
+
limit
|
|
559
|
+
];
|
|
560
|
+
const client = yield new __await(connection);
|
|
561
|
+
const stream = client.queryStream(query, params);
|
|
562
|
+
try {
|
|
563
|
+
let batchedSnapshots = [];
|
|
564
|
+
try {
|
|
565
|
+
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
566
|
+
const { payload, aggregate_id, registered_on, snapshot_id, version } = temp.value;
|
|
567
|
+
batchedSnapshots.push(import_event_sourcing2.SnapshotEnvelope.from(payload, {
|
|
568
|
+
aggregateId: aggregate_id,
|
|
569
|
+
registeredOn: registered_on,
|
|
570
|
+
snapshotId: snapshot_id,
|
|
571
|
+
version
|
|
572
|
+
}));
|
|
573
|
+
if (batchedSnapshots.length === batch) {
|
|
574
|
+
yield batchedSnapshots;
|
|
575
|
+
batchedSnapshots = [];
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
} catch (temp) {
|
|
579
|
+
error = [temp];
|
|
580
|
+
} finally {
|
|
581
|
+
try {
|
|
582
|
+
more && (temp = iter.return) && (yield new __await(temp.call(iter)));
|
|
583
|
+
} finally {
|
|
584
|
+
if (error)
|
|
585
|
+
throw error[0];
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
if (batchedSnapshots.length > 0) {
|
|
589
|
+
yield batchedSnapshots;
|
|
590
|
+
}
|
|
591
|
+
} catch (e) {
|
|
592
|
+
stream.destroy();
|
|
593
|
+
} finally {
|
|
594
|
+
yield new __await(client.release());
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
getEnvelope(_0, _1, _2) {
|
|
599
|
+
return __async(this, arguments, function* ({ streamId }, version, pool) {
|
|
600
|
+
const collection = import_event_sourcing2.SnapshotCollection.get(pool);
|
|
601
|
+
const [entity] = yield this.pool.query(`SELECT payload, aggregate_id, registered_on, snapshot_id, version FROM \`${collection}\` WHERE stream_id = ? AND version = ?`, [
|
|
602
|
+
streamId,
|
|
603
|
+
version
|
|
604
|
+
]);
|
|
605
|
+
if (!entity) {
|
|
606
|
+
throw new import_event_sourcing2.SnapshotNotFoundException(streamId, version);
|
|
607
|
+
}
|
|
608
|
+
return import_event_sourcing2.SnapshotEnvelope.from(entity.payload, {
|
|
609
|
+
aggregateId: entity.aggregate_id,
|
|
610
|
+
registeredOn: entity.registered_on,
|
|
611
|
+
snapshotId: entity.snapshot_id,
|
|
612
|
+
version: entity.version
|
|
613
|
+
});
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
getLastAggregateEnvelopes(aggregateName, filter) {
|
|
617
|
+
return __asyncGenerator(this, null, function* () {
|
|
618
|
+
const connection = this.pool.getConnection();
|
|
619
|
+
const collection = import_event_sourcing2.SnapshotCollection.get(filter == null ? void 0 : filter.pool);
|
|
620
|
+
const fromId = filter == null ? void 0 : filter.fromId;
|
|
621
|
+
const limit = (filter == null ? void 0 : filter.limit) || Number.MAX_SAFE_INTEGER;
|
|
622
|
+
const batch = (filter == null ? void 0 : filter.batch) || import_event_sourcing2.DEFAULT_BATCH_SIZE;
|
|
623
|
+
const query = `
|
|
624
|
+
SELECT payload, aggregate_id, registered_on, snapshot_id, version
|
|
625
|
+
FROM \`${collection}\`
|
|
626
|
+
WHERE aggregate_name = ?
|
|
627
|
+
AND ${fromId ? "latest >= ?" : "latest LIKE 'latest%'"}
|
|
628
|
+
LIMIT ?
|
|
629
|
+
`;
|
|
630
|
+
const params = fromId ? [
|
|
631
|
+
aggregateName,
|
|
632
|
+
fromId,
|
|
633
|
+
limit
|
|
634
|
+
] : [
|
|
635
|
+
aggregateName,
|
|
636
|
+
limit
|
|
637
|
+
];
|
|
638
|
+
const client = yield new __await(connection);
|
|
639
|
+
const stream = client.queryStream(query, params);
|
|
640
|
+
try {
|
|
641
|
+
let batchedSnapshots = [];
|
|
642
|
+
try {
|
|
643
|
+
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
644
|
+
const { payload, aggregate_id, registered_on, snapshot_id, version } = temp.value;
|
|
645
|
+
batchedSnapshots.push(import_event_sourcing2.SnapshotEnvelope.from(payload, {
|
|
646
|
+
aggregateId: aggregate_id,
|
|
647
|
+
registeredOn: registered_on,
|
|
648
|
+
snapshotId: snapshot_id,
|
|
649
|
+
version
|
|
650
|
+
}));
|
|
651
|
+
if (batchedSnapshots.length === batch) {
|
|
652
|
+
yield batchedSnapshots;
|
|
653
|
+
batchedSnapshots = [];
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
} catch (temp) {
|
|
657
|
+
error = [temp];
|
|
658
|
+
} finally {
|
|
659
|
+
try {
|
|
660
|
+
more && (temp = iter.return) && (yield new __await(temp.call(iter)));
|
|
661
|
+
} finally {
|
|
662
|
+
if (error)
|
|
663
|
+
throw error[0];
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
if (batchedSnapshots.length > 0) {
|
|
667
|
+
yield batchedSnapshots;
|
|
668
|
+
}
|
|
669
|
+
} catch (e) {
|
|
670
|
+
stream.destroy();
|
|
671
|
+
} finally {
|
|
672
|
+
yield new __await(client.release());
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
getManyLastSnapshotEnvelopes(streams, pool) {
|
|
677
|
+
return __async(this, null, function* () {
|
|
678
|
+
const collection = import_event_sourcing2.SnapshotCollection.get(pool);
|
|
679
|
+
const entities = yield this.getLastStreamEntities(collection, streams, [
|
|
680
|
+
"stream_id",
|
|
681
|
+
"payload",
|
|
682
|
+
"aggregate_id",
|
|
683
|
+
"registered_on",
|
|
684
|
+
"snapshot_id",
|
|
685
|
+
"version"
|
|
686
|
+
]);
|
|
687
|
+
return new Map(entities.map(({ stream_id, payload, aggregate_id, registered_on, snapshot_id, version }) => [
|
|
688
|
+
streams.find(({ streamId: currentStreamId }) => currentStreamId === stream_id),
|
|
689
|
+
import_event_sourcing2.SnapshotEnvelope.from(payload, {
|
|
690
|
+
aggregateId: aggregate_id,
|
|
691
|
+
registeredOn: new Date(registered_on),
|
|
692
|
+
snapshotId: snapshot_id,
|
|
693
|
+
version
|
|
694
|
+
})
|
|
695
|
+
]));
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
getLastStreamEntities(collection, streams, fields, connection) {
|
|
699
|
+
return __async(this, null, function* () {
|
|
700
|
+
const latestIds = streams.map(({ streamId }) => `latest#${streamId}`);
|
|
701
|
+
return (connection || this.pool).query(`SELECT ${fields.join(", ")}
|
|
702
|
+
FROM \`${collection}\`
|
|
703
|
+
WHERE latest IN (?)
|
|
704
|
+
`, [
|
|
705
|
+
latestIds
|
|
706
|
+
]);
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
__name(_MariaDBSnapshotStore, "MariaDBSnapshotStore");
|
|
711
|
+
var MariaDBSnapshotStore = _MariaDBSnapshotStore;
|
|
712
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
713
|
+
0 && (module.exports = {
|
|
714
|
+
MariaDBEventStore,
|
|
715
|
+
MariaDBSnapshotStore
|
|
716
|
+
});
|
package/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './dist';
|
package/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./dist"), exports);
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ocoda/event-sourcing-mariadb",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "NestJS Event Sourcing Library (@mariadb)",
|
|
5
|
+
"author": "Dries Hooghe <dries@drieshooghe.com>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/ocoda/event-sourcing/issues"
|
|
11
|
+
},
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">= 18.0.0"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"mariadb": "^3.3.1"
|
|
17
|
+
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"@nestjs/core": "^10.0.0",
|
|
20
|
+
"reflect-metadata": "^0.2.0",
|
|
21
|
+
"rxjs": "^7.2.0",
|
|
22
|
+
"@ocoda/event-sourcing": "1.0.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@biomejs/biome": "1.9.3",
|
|
26
|
+
"@faker-js/faker": "^9.0.0",
|
|
27
|
+
"@nestjs/common": "10.4.4",
|
|
28
|
+
"@nestjs/core": "10.4.4",
|
|
29
|
+
"@nestjs/platform-express": "10.4.4",
|
|
30
|
+
"@nestjs/testing": "10.4.4",
|
|
31
|
+
"@swc-node/register": "^1.5.2",
|
|
32
|
+
"@swc/core": "1.7.26",
|
|
33
|
+
"@swc/jest": "0.2.36",
|
|
34
|
+
"@types/jest": "29.5.13",
|
|
35
|
+
"@types/node": "20.16.10",
|
|
36
|
+
"jest": "29.7.0",
|
|
37
|
+
"jest-mock": "29.7.0",
|
|
38
|
+
"reflect-metadata": "0.2.2",
|
|
39
|
+
"rxjs": "7.8.1",
|
|
40
|
+
"tsup": "^8.3.0",
|
|
41
|
+
"typescript": "5.6.2",
|
|
42
|
+
"@ocoda/event-sourcing-config": "1.0.0",
|
|
43
|
+
"@ocoda/event-sourcing-testing": "1.0.0"
|
|
44
|
+
},
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "https://github.com/ocoda/event-sourcing",
|
|
48
|
+
"directory": "packages/integration/mariadb"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "rm -rf dist && tsup lib/index.ts --format cjs --dts",
|
|
52
|
+
"test": "jest --config jest.config.js",
|
|
53
|
+
"test:ci": "jest --config jest.config.js --runInBand --coverage",
|
|
54
|
+
"ci": "biome ci",
|
|
55
|
+
"format": "biome format --write",
|
|
56
|
+
"lint": "biome check --write"
|
|
57
|
+
}
|
|
58
|
+
}
|