@ocoda/event-sourcing-mariadb 1.0.0 → 1.0.2

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 CHANGED
@@ -1,5 +1,25 @@
1
1
  # @ocoda/event-sourcing-mariadb
2
2
 
3
+ ## 1.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#361](https://github.com/ocoda/event-sourcing/pull/361) [`5be1d42`](https://github.com/ocoda/event-sourcing/commit/5be1d42d1eb0a19a252d2127b72a756b3cd701f6) Thanks [@renovate](https://github.com/apps/renovate)! - Dependency updates
8
+
9
+ - Updated dependencies [[`5be1d42`](https://github.com/ocoda/event-sourcing/commit/5be1d42d1eb0a19a252d2127b72a756b3cd701f6)]:
10
+ - @ocoda/event-sourcing@1.0.2
11
+
12
+ ## 1.0.1
13
+
14
+ ### Patch Changes
15
+
16
+ - [#362](https://github.com/ocoda/event-sourcing/pull/362) [`8081e16`](https://github.com/ocoda/event-sourcing/commit/8081e16d3edcab21efa301a7e1261cfd062ab4e7) Thanks [@drieshooghe](https://github.com/drieshooghe)! - Introduce ULID based event-ids and make sure these are persisted/retrieved correctly within the integrations
17
+
18
+ - [#362](https://github.com/ocoda/event-sourcing/pull/362) [`94e41eb`](https://github.com/ocoda/event-sourcing/commit/94e41ebea9a5d3762d39db0a3afb664bc0d78010) Thanks [@drieshooghe](https://github.com/drieshooghe)! - Adds a `listCollections` method to all integrations
19
+
20
+ - Updated dependencies [[`8081e16`](https://github.com/ocoda/event-sourcing/commit/8081e16d3edcab21efa301a7e1261cfd062ab4e7), [`94e41eb`](https://github.com/ocoda/event-sourcing/commit/94e41ebea9a5d3762d39db0a3afb664bc0d78010)]:
21
+ - @ocoda/event-sourcing@1.0.1
22
+
3
23
  ## 1.0.0
4
24
 
5
25
  ### Major Changes
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ <p align="center">
2
+ <a href="http://ocoda.io/" target="blank"><img src="https://github.com/ocoda/.github/raw/master/assets/ocoda_logo_full_gradient.svg" width="600" alt="Ocoda Logo" /></a>
3
+ </p>
4
+
5
+ <p align="center">
6
+ <a href="https://github.com/ocoda/event-sourcing/actions/workflows/ci-libraries.yml">
7
+ <img src="https://github.com/ocoda/event-sourcing/actions/workflows/ci-libraries.yml/badge.svg">
8
+ </a>
9
+ <a href="https://codecov.io/gh/ocoda/event-sourcing">
10
+ <img src="https://codecov.io/gh/ocoda/event-sourcing/branch/master/graph/badge.svg?token=D6BRXUY0J8">
11
+ </a>
12
+ <a href="https://github.com/ocoda/event-sourcing/blob/master/LICENSE.md">
13
+ <img src="https://img.shields.io/badge/License-MIT-green.svg">
14
+ </a>
15
+ </p>
16
+ <p align="center">
17
+ <a href="https://github.com/ocoda/event-sourcing/issues/new?labels=bug&template=bug_report.md">Report a bug</a>
18
+ &nbsp;|&nbsp;
19
+ <a href="https://github.com/ocoda/event-sourcing/issues/new?labels=enhancement&template=feature_request.md">Request a feature</a>
20
+ </p>
21
+
22
+ ## About this library
23
+
24
+ This is a complementing module for `@ocoda/event-sourcing`, a powerful library designed to simplify the implementation of advanced architectural patterns in your [**NestJS**](https://nestjs.com/) application. It provides essential building blocks to help you implement Domain-Driven Design (DDD), CQRS and leverage Event Sourcing to tackle the complexities of modern systems.
25
+
26
+ This store-driver library uses [MariaDB](https://mariadb.com/) as an underlying driver for event- and snapshot-stores, and needs to be installed together with the core module `@ocoda/event-sourcing` in order to get started.
27
+
28
+ ## Documentation 📗
29
+ Ready to dive right in? Visit [the documentation](https://ocoda.github.io/event-sourcing) to find out how to get started.
30
+
31
+ ## Contact
32
+ dries@drieshooghe.com
33
+ &nbsp;
34
+
35
+ ## Acknowledgments
36
+ This library is inspired by [@nestjs/cqrs](https://github.com/nestjs/cqrs)
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
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';
1
+ import { IEventPayload, IEvent, EventStore, IEventPool, IEventCollection, IEventCollectionFilter, EventStream, IEventFilter, EventEnvelope, EventStoreConfig, AggregateRoot, ISnapshot, SnapshotStore, ISnapshotPool, ISnapshotCollection, ISnapshotCollectionFilter, SnapshotStream, ISnapshotFilter, SnapshotEnvelope, ILatestSnapshotFilter, SnapshotStoreConfig } from '@ocoda/event-sourcing';
2
2
  import { Type } from '@nestjs/common';
3
3
  import { PoolConfig } from 'mariadb';
4
4
 
@@ -19,9 +19,10 @@ declare class MariaDBEventStore extends EventStore<MariaDBEventStoreConfig> {
19
19
  connect(): Promise<void>;
20
20
  disconnect(): Promise<void>;
21
21
  ensureCollection(pool?: IEventPool): Promise<IEventCollection>;
22
+ listCollections(filter?: IEventCollectionFilter): AsyncGenerator<IEventCollection[]>;
22
23
  getEvents({ streamId }: EventStream, filter?: IEventFilter): AsyncGenerator<IEvent[]>;
23
24
  getEvent({ streamId }: EventStream, version: number, pool?: IEventPool): Promise<IEvent>;
24
- appendEvents(stream: EventStream, aggregateVersion: number, events: IEvent[], pool?: IEventPool): Promise<EventEnvelope[]>;
25
+ appendEvents(stream: EventStream, aggregateVersion: number, events: IEvent[] | EventEnvelope[], pool?: IEventPool): Promise<EventEnvelope[]>;
25
26
  getEnvelopes({ streamId }: EventStream, filter?: IEventFilter): AsyncGenerator<EventEnvelope[]>;
26
27
  getEnvelope({ streamId }: EventStream, version: number, pool?: IEventPool): Promise<EventEnvelope>;
27
28
  }
@@ -46,7 +47,7 @@ declare class MariaDBSnapshotStore extends SnapshotStore<MariaDBSnapshotStoreCon
46
47
  connect(): Promise<void>;
47
48
  disconnect(): Promise<void>;
48
49
  ensureCollection(pool?: ISnapshotPool): Promise<ISnapshotCollection>;
49
- stop(): Promise<void>;
50
+ listCollections(filter?: ISnapshotCollectionFilter): AsyncGenerator<ISnapshotCollection[]>;
50
51
  getSnapshots<A extends AggregateRoot>({ streamId }: SnapshotStream, filter?: ISnapshotFilter): AsyncGenerator<ISnapshot<A>[]>;
51
52
  getSnapshot<A extends AggregateRoot>({ streamId }: SnapshotStream, version: number, pool?: ISnapshotPool): Promise<ISnapshot<A>>;
52
53
  appendSnapshot<A extends AggregateRoot>(stream: SnapshotStream, aggregateVersion: number, snapshot: ISnapshot<A>, pool?: ISnapshotPool): Promise<SnapshotEnvelope<A>>;
package/dist/index.js CHANGED
@@ -98,7 +98,8 @@ var _MariaDBEventStore = class _MariaDBEventStore extends import_event_sourcing.
98
98
  occurred_on TIMESTAMP NOT NULL,
99
99
  correlation_id VARCHAR(255),
100
100
  causation_id VARCHAR(255),
101
- PRIMARY KEY (stream_id, version)
101
+ PRIMARY KEY (stream_id, version),
102
+ INDEX idx_event_id (event_id)
102
103
  )`);
103
104
  return collection;
104
105
  } catch (error) {
@@ -106,6 +107,44 @@ var _MariaDBEventStore = class _MariaDBEventStore extends import_event_sourcing.
106
107
  }
107
108
  });
108
109
  }
110
+ listCollections(filter) {
111
+ return __asyncGenerator(this, null, function* () {
112
+ const connection = this.pool.getConnection();
113
+ const batch = (filter == null ? void 0 : filter.batch) || import_event_sourcing.DEFAULT_BATCH_SIZE;
114
+ const query = "SELECT TABLE_NAME FROM information_schema.tables WHERE BINARY table_name LIKE '%events'";
115
+ const client = yield new __await(connection);
116
+ const stream = client.queryStream(query);
117
+ try {
118
+ let batchedCollections = [];
119
+ try {
120
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
121
+ const { TABLE_NAME } = temp.value;
122
+ batchedCollections.push(TABLE_NAME);
123
+ if (batchedCollections.length === batch) {
124
+ yield batchedCollections;
125
+ batchedCollections = [];
126
+ }
127
+ }
128
+ } catch (temp) {
129
+ error = [temp];
130
+ } finally {
131
+ try {
132
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
133
+ } finally {
134
+ if (error)
135
+ throw error[0];
136
+ }
137
+ }
138
+ if (batchedCollections.length > 0) {
139
+ yield batchedCollections;
140
+ }
141
+ } catch (e) {
142
+ stream.destroy();
143
+ } finally {
144
+ yield new __await(client.release());
145
+ }
146
+ });
147
+ }
109
148
  getEvents(_0, _1) {
110
149
  return __asyncGenerator(this, arguments, function* ({ streamId }, filter) {
111
150
  const connection = this.pool.getConnection();
@@ -190,11 +229,17 @@ var _MariaDBEventStore = class _MariaDBEventStore extends import_event_sourcing.
190
229
  }
191
230
  let version = aggregateVersion - events.length + 1;
192
231
  const envelopes = [];
232
+ const eventIdFactory = import_event_sourcing.EventId.factory();
193
233
  for (const event of events) {
234
+ if (event instanceof import_event_sourcing.EventEnvelope) {
235
+ envelopes.push(event);
236
+ continue;
237
+ }
194
238
  const name = this.eventMap.getName(event);
195
239
  const payload = this.eventMap.serializeEvent(event);
196
240
  const envelope = import_event_sourcing.EventEnvelope.create(name, payload, {
197
241
  aggregateId: stream.aggregateId,
242
+ eventId: eventIdFactory(),
198
243
  version: version++
199
244
  });
200
245
  envelopes.push(envelope);
@@ -207,7 +252,7 @@ var _MariaDBEventStore = class _MariaDBEventStore extends import_event_sourcing.
207
252
  metadata.version,
208
253
  event,
209
254
  JSON.stringify(payload),
210
- metadata.eventId,
255
+ metadata.eventId.value,
211
256
  metadata.aggregateId,
212
257
  metadata.occurredOn,
213
258
  (_a = metadata.correlationId) != null ? _a : null,
@@ -261,7 +306,7 @@ var _MariaDBEventStore = class _MariaDBEventStore extends import_event_sourcing.
261
306
  for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
262
307
  const { event, payload, event_id, aggregate_id, version, occurred_on, correlation_id, causation_id } = temp.value;
263
308
  batchedEvents.push(import_event_sourcing.EventEnvelope.from(event, payload, {
264
- eventId: event_id,
309
+ eventId: import_event_sourcing.EventId.from(event_id),
265
310
  aggregateId: aggregate_id,
266
311
  version,
267
312
  occurredOn: occurred_on,
@@ -304,7 +349,7 @@ var _MariaDBEventStore = class _MariaDBEventStore extends import_event_sourcing.
304
349
  throw new import_event_sourcing.EventNotFoundException(streamId, version);
305
350
  }
306
351
  return import_event_sourcing.EventEnvelope.from(entity.event, entity.payload, {
307
- eventId: entity.event_id,
352
+ eventId: import_event_sourcing.EventId.from(entity.event_id),
308
353
  aggregateId: entity.aggregate_id,
309
354
  version: entity.version,
310
355
  occurredOn: entity.occurred_on,
@@ -359,10 +404,42 @@ var _MariaDBSnapshotStore = class _MariaDBSnapshotStore extends import_event_sou
359
404
  }
360
405
  });
361
406
  }
362
- stop() {
363
- return __async(this, null, function* () {
364
- this.logger.log("Stopping store");
365
- yield this.pool.end();
407
+ listCollections(filter) {
408
+ return __asyncGenerator(this, null, function* () {
409
+ const connection = this.pool.getConnection();
410
+ const batch = (filter == null ? void 0 : filter.batch) || import_event_sourcing2.DEFAULT_BATCH_SIZE;
411
+ const query = "SELECT TABLE_NAME FROM information_schema.tables WHERE BINARY table_name LIKE '%snapshots'";
412
+ const client = yield new __await(connection);
413
+ const stream = client.queryStream(query);
414
+ try {
415
+ let batchedCollections = [];
416
+ try {
417
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
418
+ const { TABLE_NAME } = temp.value;
419
+ batchedCollections.push(TABLE_NAME);
420
+ if (batchedCollections.length === batch) {
421
+ yield batchedCollections;
422
+ batchedCollections = [];
423
+ }
424
+ }
425
+ } catch (temp) {
426
+ error = [temp];
427
+ } finally {
428
+ try {
429
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
430
+ } finally {
431
+ if (error)
432
+ throw error[0];
433
+ }
434
+ }
435
+ if (batchedCollections.length > 0) {
436
+ yield batchedCollections;
437
+ }
438
+ } catch (e) {
439
+ stream.destroy();
440
+ } finally {
441
+ yield new __await(client.release());
442
+ }
366
443
  });
367
444
  }
368
445
  getSnapshots(_0, _1) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ocoda/event-sourcing-mariadb",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "NestJS Event Sourcing Library (@mariadb)",
5
5
  "author": "Dries Hooghe <dries@drieshooghe.com>",
6
6
  "license": "MIT",
@@ -10,35 +10,35 @@
10
10
  "url": "https://github.com/ocoda/event-sourcing/issues"
11
11
  },
12
12
  "engines": {
13
- "node": ">= 18.0.0"
13
+ "node": ">= 18.20.4"
14
14
  },
15
15
  "dependencies": {
16
- "mariadb": "^3.3.1"
16
+ "mariadb": "^3.3.2"
17
17
  },
18
18
  "peerDependencies": {
19
19
  "@nestjs/core": "^10.0.0",
20
20
  "reflect-metadata": "^0.2.0",
21
21
  "rxjs": "^7.2.0",
22
- "@ocoda/event-sourcing": "1.0.0"
22
+ "@ocoda/event-sourcing": "1.0.2"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@biomejs/biome": "1.9.3",
26
- "@faker-js/faker": "^9.0.0",
26
+ "@faker-js/faker": "^9.0.3",
27
27
  "@nestjs/common": "10.4.4",
28
28
  "@nestjs/core": "10.4.4",
29
29
  "@nestjs/platform-express": "10.4.4",
30
30
  "@nestjs/testing": "10.4.4",
31
- "@swc-node/register": "^1.5.2",
32
- "@swc/core": "1.7.26",
31
+ "@swc-node/register": "^1.10.9",
32
+ "@swc/core": "1.7.35",
33
33
  "@swc/jest": "0.2.36",
34
34
  "@types/jest": "29.5.13",
35
- "@types/node": "20.16.10",
35
+ "@types/node": "20.16.11",
36
36
  "jest": "29.7.0",
37
37
  "jest-mock": "29.7.0",
38
38
  "reflect-metadata": "0.2.2",
39
39
  "rxjs": "7.8.1",
40
40
  "tsup": "^8.3.0",
41
- "typescript": "5.6.2",
41
+ "typescript": "5.6.3",
42
42
  "@ocoda/event-sourcing-config": "1.0.0",
43
43
  "@ocoda/event-sourcing-testing": "1.0.0"
44
44
  },
@@ -50,7 +50,7 @@
50
50
  "scripts": {
51
51
  "build": "rm -rf dist && tsup lib/index.ts --format cjs --dts",
52
52
  "test": "jest --config jest.config.js",
53
- "test:ci": "jest --config jest.config.js --runInBand --coverage",
53
+ "test:cov": "jest --config jest.config.js --coverage --collectCoverageFrom=lib/**/*.ts",
54
54
  "ci": "biome ci",
55
55
  "format": "biome format --write",
56
56
  "lint": "biome check --write"