event-store-adapter-js 2.1.32 → 2.1.34-snapshot.1

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.
Files changed (34) hide show
  1. package/.mise.toml +2 -0
  2. package/biome.json +26 -0
  3. package/dist/event-store-options.d.ts +3 -3
  4. package/dist/event-store-with-options.d.ts +4 -4
  5. package/dist/event-store.d.ts +5 -5
  6. package/dist/event-store.js +1 -1
  7. package/dist/internal/default-key-resolver.d.ts +1 -1
  8. package/dist/internal/default-serializer.d.ts +1 -1
  9. package/dist/internal/default-serializer.js +2 -2
  10. package/dist/internal/event-store-for-dynamodb.d.ts +3 -3
  11. package/dist/internal/event-store-for-dynamodb.js +31 -39
  12. package/dist/internal/event-store-for-memory.d.ts +2 -2
  13. package/dist/internal/event-store-for-memory.js +1 -4
  14. package/dist/types.d.ts +1 -1
  15. package/package.json +7 -12
  16. package/src/event-store-options.ts +3 -3
  17. package/src/event-store-with-options.ts +4 -4
  18. package/src/event-store.ts +11 -11
  19. package/src/internal/default-key-resolver.ts +1 -1
  20. package/src/internal/default-serializer.ts +3 -3
  21. package/src/internal/event-store-for-dynamodb.test.ts +14 -12
  22. package/src/internal/event-store-for-dynamodb.ts +55 -59
  23. package/src/internal/event-store-for-memory.test.ts +7 -5
  24. package/src/internal/event-store-for-memory.ts +3 -6
  25. package/src/internal/test/dynamodb-utils.ts +2 -2
  26. package/src/internal/test/user-account-event.ts +7 -4
  27. package/src/internal/test/user-account-id.ts +2 -2
  28. package/src/internal/test/user-account-repository.test.ts +14 -12
  29. package/src/internal/test/user-account-repository.ts +8 -9
  30. package/src/internal/test/user-account.ts +8 -6
  31. package/src/types.ts +13 -13
  32. package/.eslintrc.cjs +0 -25
  33. package/.prettierignore +0 -2
  34. package/.prettierrc.yml +0 -3
package/.mise.toml ADDED
@@ -0,0 +1,2 @@
1
+ [tools]
2
+ node = "20"
package/biome.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/1.7.0/schema.json",
3
+ "organizeImports": {
4
+ "enabled": true
5
+ },
6
+ "vcs": {
7
+ "enabled": true,
8
+ "clientKind": "git",
9
+ "useIgnoreFile": true
10
+ },
11
+ "formatter": {
12
+ "enabled": true,
13
+ "indentStyle": "space",
14
+ "indentWidth": 2,
15
+ "lineWidth": 80
16
+ },
17
+ "linter": {
18
+ "enabled": true,
19
+ "rules": {
20
+ "recommended": true,
21
+ "complexity": {
22
+ "noStaticOnlyClass": "off"
23
+ }
24
+ }
25
+ }
26
+ }
@@ -1,5 +1,5 @@
1
- import { Aggregate, AggregateId, Event, EventSerializer, KeyResolver, Logger, SnapshotSerializer } from "./types";
2
- import moment from "moment";
1
+ import type moment from "moment";
2
+ import type { Aggregate, AggregateId, Event, EventSerializer, KeyResolver, Logger, SnapshotSerializer } from "./types";
3
3
  interface EventStoreOptions<This extends EventStoreOptions<This, AID, A, E>, AID extends AggregateId, A extends Aggregate<A, AID>, E extends Event<AID>> {
4
4
  withKeepSnapshotCount(keepSnapshotCount: number): This;
5
5
  withDeleteTtl(deleteTtl: moment.Duration): This;
@@ -8,4 +8,4 @@ interface EventStoreOptions<This extends EventStoreOptions<This, AID, A, E>, AID
8
8
  withSnapshotSerializer(snapshotSerializer: SnapshotSerializer<AID, A>): This;
9
9
  withLogger(logger: Logger): This;
10
10
  }
11
- export { EventStoreOptions };
11
+ export type { EventStoreOptions };
@@ -1,6 +1,6 @@
1
- import { Aggregate, AggregateId, Event } from "./types";
2
- import { EventStoreOptions } from "./event-store-options";
3
- import { EventStore } from "./event-store";
1
+ import type { EventStore } from "./event-store";
2
+ import type { EventStoreOptions } from "./event-store-options";
3
+ import type { Aggregate, AggregateId, Event } from "./types";
4
4
  interface EventStoreWithOptions<AID extends AggregateId, A extends Aggregate<A, AID>, E extends Event<AID>> extends EventStore<AID, A, E>, EventStoreOptions<EventStoreWithOptions<AID, A, E>, AID, A, E> {
5
5
  }
6
- export { EventStoreWithOptions };
6
+ export type { EventStoreWithOptions };
@@ -1,7 +1,7 @@
1
- import { Aggregate, AggregateId, Event, EventSerializer, KeyResolver, Logger, SnapshotSerializer } from "./types";
2
- import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
3
- import moment from "moment";
4
- import { EventStoreWithOptions } from "./event-store-with-options";
1
+ import type { DynamoDBClient } from "@aws-sdk/client-dynamodb";
2
+ import type moment from "moment";
3
+ import type { EventStoreWithOptions } from "./event-store-with-options";
4
+ import type { Aggregate, AggregateId, Event, EventSerializer, KeyResolver, Logger, SnapshotSerializer } from "./types";
5
5
  interface EventStore<AID extends AggregateId, A extends Aggregate<A, AID>, E extends Event<AID>> {
6
6
  persistEvent(event: E, version: number): Promise<void>;
7
7
  persistEventAndSnapshot(event: E, aggregate: A): Promise<void>;
@@ -12,4 +12,4 @@ declare class EventStoreFactory {
12
12
  static ofDynamoDB<AID extends AggregateId, A extends Aggregate<A, AID>, E extends Event<AID>>(dynamodbClient: DynamoDBClient, journalTableName: string, snapshotTableName: string, journalAidIndexName: string, snapshotAidIndexName: string, shardCount: number, eventConverter: (json: string) => E, snapshotConverter: (json: string) => A, keepSnapshotCount?: number | undefined, deleteTtl?: moment.Duration | undefined, keyResolver?: KeyResolver<AID>, eventSerializer?: EventSerializer<AID, E>, snapshotSerializer?: SnapshotSerializer<AID, A>, logger?: Logger | undefined): EventStoreWithOptions<AID, A, E>;
13
13
  static ofMemory<AID extends AggregateId, A extends Aggregate<A, AID>, E extends Event<AID>>(events?: Map<AID, E[]>, snapshots?: Map<AID, A>): EventStore<AID, A, E>;
14
14
  }
15
- export { EventStore, EventStoreFactory };
15
+ export { type EventStore, EventStoreFactory };
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EventStoreFactory = void 0;
4
- const event_store_for_dynamodb_1 = require("./internal/event-store-for-dynamodb");
5
4
  const default_key_resolver_1 = require("./internal/default-key-resolver");
6
5
  const default_serializer_1 = require("./internal/default-serializer");
6
+ const event_store_for_dynamodb_1 = require("./internal/event-store-for-dynamodb");
7
7
  const event_store_for_memory_1 = require("./internal/event-store-for-memory");
8
8
  class EventStoreFactory {
9
9
  static ofDynamoDB(dynamodbClient, journalTableName, snapshotTableName, journalAidIndexName, snapshotAidIndexName, shardCount, eventConverter, snapshotConverter, keepSnapshotCount = undefined, deleteTtl = undefined, keyResolver = new default_key_resolver_1.DefaultKeyResolver(), eventSerializer = new default_serializer_1.JsonEventSerializer(), snapshotSerializer = new default_serializer_1.JsonSnapshotSerializer(), logger = undefined) {
@@ -1,4 +1,4 @@
1
- import { AggregateId, KeyResolver } from "../types";
1
+ import type { AggregateId, KeyResolver } from "../types";
2
2
  declare class DefaultKeyResolver<AID extends AggregateId> implements KeyResolver<AID> {
3
3
  private hashString;
4
4
  resolvePartitionKey(aggregateId: AID, shardCount: number): string;
@@ -1,4 +1,4 @@
1
- import { Aggregate, AggregateId, Event, EventSerializer, SnapshotSerializer } from "../types";
1
+ import type { Aggregate, AggregateId, Event, EventSerializer, SnapshotSerializer } from "../types";
2
2
  declare class JsonEventSerializer<AID extends AggregateId, E extends Event<AID>> implements EventSerializer<AID, E> {
3
3
  private encoder;
4
4
  private decoder;
@@ -6,7 +6,7 @@ class JsonEventSerializer {
6
6
  this.encoder = new TextEncoder();
7
7
  this.decoder = new TextDecoder();
8
8
  }
9
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ // biome-ignore lint/suspicious/noExplicitAny:
10
10
  deserialize(bytes, converter) {
11
11
  const jsonString = this.decoder.decode(bytes);
12
12
  const json = JSON.parse(jsonString);
@@ -26,7 +26,7 @@ class JsonSnapshotSerializer {
26
26
  this.encoder = new TextEncoder();
27
27
  this.decoder = new TextDecoder();
28
28
  }
29
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ // biome-ignore lint/suspicious/noExplicitAny:
30
30
  deserialize(bytes, converter) {
31
31
  const jsonString = this.decoder.decode(bytes);
32
32
  const obj = JSON.parse(jsonString);
@@ -1,7 +1,7 @@
1
- import { Aggregate, AggregateId, Event, EventSerializer, KeyResolver, Logger, SnapshotSerializer } from "../types";
2
- import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
1
+ import { type DynamoDBClient } from "@aws-sdk/client-dynamodb";
3
2
  import moment from "moment/moment";
4
- import { EventStoreWithOptions } from "../event-store-with-options";
3
+ import type { EventStoreWithOptions } from "../event-store-with-options";
4
+ import { type Aggregate, type AggregateId, type Event, type EventSerializer, type KeyResolver, type Logger, type SnapshotSerializer } from "../types";
5
5
  declare class EventStoreForDynamoDB<AID extends AggregateId, A extends Aggregate<A, AID>, E extends Event<AID>> implements EventStoreWithOptions<AID, A, E> {
6
6
  private dynamodbClient;
7
7
  private journalTableName;
@@ -13,9 +13,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.EventStoreForDynamoDB = void 0;
16
- const types_1 = require("../types");
17
16
  const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
18
17
  const moment_1 = __importDefault(require("moment/moment"));
18
+ const types_1 = require("../types");
19
19
  const default_key_resolver_1 = require("./default-key-resolver");
20
20
  const default_serializer_1 = require("./default-serializer");
21
21
  class EventStoreForDynamoDB {
@@ -92,20 +92,18 @@ class EventStoreForDynamoDB {
92
92
  if (queryResult.Items === undefined || queryResult.Items.length === 0) {
93
93
  return undefined;
94
94
  }
95
- else {
96
- const item = queryResult.Items[0];
97
- const version = item.version.N;
98
- if (version === undefined) {
99
- throw new Error("Version is undefined");
100
- }
101
- const payload = item.payload.B;
102
- if (payload === undefined) {
103
- throw new Error("Payload is undefined");
104
- }
105
- const result = this.snapshotSerializer.deserialize(payload, this.snapshotConverter);
106
- (_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug(`getLatestSnapshotById(${JSON.stringify(id)}, ...): finished`);
107
- return result.withVersion(Number(version));
95
+ const item = queryResult.Items[0];
96
+ const version = item.version.N;
97
+ if (version === undefined) {
98
+ throw new Error("Version is undefined");
99
+ }
100
+ const payload = item.payload.B;
101
+ if (payload === undefined) {
102
+ throw new Error("Payload is undefined");
108
103
  }
104
+ const result = this.snapshotSerializer.deserialize(payload, this.snapshotConverter);
105
+ (_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug(`getLatestSnapshotById(${JSON.stringify(id)}, ...): finished`);
106
+ return result.withVersion(Number(version));
109
107
  });
110
108
  }
111
109
  persistEvent(event, version) {
@@ -177,14 +175,12 @@ class EventStoreForDynamoDB {
177
175
  }
178
176
  catch (e) {
179
177
  if (e instanceof client_dynamodb_1.TransactionCanceledException &&
180
- ((_b = e.CancellationReasons) === null || _b === void 0 ? void 0 : _b.some((e) => e.Code == "ConditionalCheckFailed"))) {
178
+ ((_b = e.CancellationReasons) === null || _b === void 0 ? void 0 : _b.some((e) => e.Code === "ConditionalCheckFailed"))) {
181
179
  throw new types_1.OptimisticLockError("Optimistic locking failed", e);
182
180
  }
183
- else {
184
- throw e;
185
- }
181
+ throw e;
186
182
  }
187
- (_c = this.logger) === null || _c === void 0 ? void 0 : _c.debug(`private createEventAndSnapshot(...): finished`);
183
+ (_c = this.logger) === null || _c === void 0 ? void 0 : _c.debug("private createEventAndSnapshot(...): finished");
188
184
  });
189
185
  }
190
186
  updateEventAndSnapshotOpt(event, version, aggregate) {
@@ -209,14 +205,12 @@ class EventStoreForDynamoDB {
209
205
  }
210
206
  catch (e) {
211
207
  if (e instanceof client_dynamodb_1.TransactionCanceledException &&
212
- ((_b = e.CancellationReasons) === null || _b === void 0 ? void 0 : _b.some((e) => e.Code == "ConditionalCheckFailed"))) {
208
+ ((_b = e.CancellationReasons) === null || _b === void 0 ? void 0 : _b.some((e) => e.Code === "ConditionalCheckFailed"))) {
213
209
  throw new types_1.OptimisticLockError("Optimistic locking failed", e);
214
210
  }
215
- else {
216
- throw e;
217
- }
211
+ throw e;
218
212
  }
219
- (_c = this.logger) === null || _c === void 0 ? void 0 : _c.debug(`private updateEventAndSnapshotOpt(...): finished`);
213
+ (_c = this.logger) === null || _c === void 0 ? void 0 : _c.debug("private updateEventAndSnapshotOpt(...): finished");
220
214
  });
221
215
  }
222
216
  putJournal(event) {
@@ -237,7 +231,7 @@ class EventStoreForDynamoDB {
237
231
  },
238
232
  ConditionExpression: "attribute_not_exists(pkey) AND attribute_not_exists(skey)",
239
233
  };
240
- (_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug(`private putSnapshot(...): finished`);
234
+ (_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug("private putSnapshot(...): finished");
241
235
  return result;
242
236
  }
243
237
  putSnapshot(event, sequenceNumber, aggregate) {
@@ -262,8 +256,8 @@ class EventStoreForDynamoDB {
262
256
  },
263
257
  ConditionExpression: "attribute_not_exists(pkey) AND attribute_not_exists(skey)",
264
258
  };
265
- (_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug("result = " + JSON.stringify(result));
266
- (_c = this.logger) === null || _c === void 0 ? void 0 : _c.debug(`private putSnapshot(...): finished`);
259
+ (_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug(`result = ${JSON.stringify(result)}`);
260
+ (_c = this.logger) === null || _c === void 0 ? void 0 : _c.debug("private putSnapshot(...): finished");
267
261
  return result;
268
262
  }
269
263
  updateSnapshot(event, sequenceNumber, version, aggregate) {
@@ -308,8 +302,8 @@ class EventStoreForDynamoDB {
308
302
  ConditionExpression: "#version=:before_version",
309
303
  };
310
304
  }
311
- (_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug("result = " + JSON.stringify(result));
312
- (_c = this.logger) === null || _c === void 0 ? void 0 : _c.debug(`private updateSnapshot(...): finished`);
305
+ (_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug(`result·=·${JSON.stringify(result)}`);
306
+ (_c = this.logger) === null || _c === void 0 ? void 0 : _c.debug("private·updateSnapshot(...)finished");
313
307
  return result;
314
308
  }
315
309
  tryPurgeExcessSnapshots(event) {
@@ -370,16 +364,14 @@ class EventStoreForDynamoDB {
370
364
  if (queryResult.Items === undefined || queryResult.Items.length === 0) {
371
365
  return undefined;
372
366
  }
373
- else {
374
- return queryResult.Items.map((item) => {
375
- const pkey = item.pkey.S;
376
- const skey = item.skey.S;
377
- if (pkey === undefined || skey === undefined) {
378
- throw new Error("pkey or skey is undefined");
379
- }
380
- return { pkey, skey };
381
- });
382
- }
367
+ return queryResult.Items.map((item) => {
368
+ const pkey = item.pkey.S;
369
+ const skey = item.skey.S;
370
+ if (pkey === undefined || skey === undefined) {
371
+ throw new Error("pkey or skey is undefined");
372
+ }
373
+ return { pkey, skey };
374
+ });
383
375
  });
384
376
  }
385
377
  updateTtlOfExcessSnapshots(aggregateId) {
@@ -1,5 +1,5 @@
1
- import { Aggregate, AggregateId, Event } from "../types";
2
- import { EventStore } from "../event-store";
1
+ import type { EventStore } from "../event-store";
2
+ import type { Aggregate, AggregateId, Event } from "../types";
3
3
  declare class EventStoreForMemory<AID extends AggregateId, A extends Aggregate<A, AID>, E extends Event<AID>> implements EventStore<AID, A, E> {
4
4
  private readonly events;
5
5
  private readonly snapshots;
@@ -30,10 +30,7 @@ class EventStoreForMemory {
30
30
  throw new Error("snapshot is undefined");
31
31
  }
32
32
  if (snapshot.id.asString() !== event.aggregateId.asString()) {
33
- throw new Error("aggregateId mismatch: snapshot.id = " +
34
- snapshot.id.asString() +
35
- ", event.aggregateId = " +
36
- event.aggregateId.asString());
33
+ throw new Error(`aggregateId·mismatchsnapshot.id·=·${snapshot.id.asString()},·event.aggregateId·=·${event.aggregateId.asString()}`);
37
34
  }
38
35
  if (snapshot.version !== version) {
39
36
  throw new Error("version mismatch");
package/dist/types.d.ts CHANGED
@@ -41,4 +41,4 @@ export interface Logger {
41
41
  declare class OptimisticLockError extends Error {
42
42
  constructor(message: string, cause?: Error);
43
43
  }
44
- export { AggregateId, Aggregate, Event, KeyResolver, EventSerializer, SnapshotSerializer, OptimisticLockError, };
44
+ export { type AggregateId, type Aggregate, type Event, type KeyResolver, type EventSerializer, type SnapshotSerializer, OptimisticLockError, };
package/package.json CHANGED
@@ -1,18 +1,14 @@
1
1
  {
2
2
  "name": "event-store-adapter-js",
3
- "version": "2.1.32",
3
+ "version": "2.1.34-snapshot.1",
4
4
  "description": "This library is designed to turn DynamoDB into an Event Store for Event Sourcing.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
8
8
  "build": "tsc && rm -f dist/internal/*.test.d.ts && rm -f dist/internal/*.test.js && rm -fr dist/internal/test",
9
9
  "test": "jest --no-cache",
10
- "fix": "npm run fix:prettier && npm run fix:eslint",
11
- "fix:eslint": "eslint --fix .",
12
- "fix:prettier": "prettier --write \"**/*.{js,ts,jsx,tsx,json}\"",
13
- "lint": "npm run lint:prettier && npm run lint:eslint",
14
- "lint:eslint": "eslint .",
15
- "lint:prettier": "prettier --check \"**/*.{js,ts,jsx,tsx,json}\"",
10
+ "lint": "biome check",
11
+ "fix": "biome format --write *",
16
12
  "clean": "rimraf ./dist"
17
13
  },
18
14
  "repository": {
@@ -31,15 +27,14 @@
31
27
  "author": "Junichi Kato <j5ik2o@gmail.com>",
32
28
  "license": "MIT",
33
29
  "devDependencies": {
30
+ "@biomejs/biome": "1.8.3",
34
31
  "@types/jest": "^29.5.5",
35
32
  "@types/node": "^20.6.0",
36
33
  "@types/winston": "^2.4.4",
37
- "@typescript-eslint/eslint-plugin": "^7.0.0",
38
- "@typescript-eslint/parser": "^7.0.0",
39
- "eslint": "^8.47.0",
34
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
35
+ "@typescript-eslint/parser": "^8.0.0",
40
36
  "jest": "^29.7.0",
41
- "prettier": "3.2.5",
42
- "rimraf": "^5.0.1",
37
+ "rimraf": "6.0.1",
43
38
  "testcontainers": "^10.2.1",
44
39
  "ts-jest": "^29.1.1",
45
40
  "ts-node": "^10.9.1",
@@ -1,4 +1,5 @@
1
- import {
1
+ import type moment from "moment";
2
+ import type {
2
3
  Aggregate,
3
4
  AggregateId,
4
5
  Event,
@@ -7,7 +8,6 @@ import {
7
8
  Logger,
8
9
  SnapshotSerializer,
9
10
  } from "./types";
10
- import moment from "moment";
11
11
 
12
12
  interface EventStoreOptions<
13
13
  This extends EventStoreOptions<This, AID, A, E>,
@@ -28,4 +28,4 @@ interface EventStoreOptions<
28
28
  withLogger(logger: Logger): This;
29
29
  }
30
30
 
31
- export { EventStoreOptions };
31
+ export type { EventStoreOptions };
@@ -1,6 +1,6 @@
1
- import { Aggregate, AggregateId, Event } from "./types";
2
- import { EventStoreOptions } from "./event-store-options";
3
- import { EventStore } from "./event-store";
1
+ import type { EventStore } from "./event-store";
2
+ import type { EventStoreOptions } from "./event-store-options";
3
+ import type { Aggregate, AggregateId, Event } from "./types";
4
4
 
5
5
  interface EventStoreWithOptions<
6
6
  AID extends AggregateId,
@@ -9,4 +9,4 @@ interface EventStoreWithOptions<
9
9
  > extends EventStore<AID, A, E>,
10
10
  EventStoreOptions<EventStoreWithOptions<AID, A, E>, AID, A, E> {}
11
11
 
12
- export { EventStoreWithOptions };
12
+ export type { EventStoreWithOptions };
@@ -1,4 +1,14 @@
1
+ import type { DynamoDBClient } from "@aws-sdk/client-dynamodb";
2
+ import type moment from "moment";
3
+ import type { EventStoreWithOptions } from "./event-store-with-options";
4
+ import { DefaultKeyResolver } from "./internal/default-key-resolver";
1
5
  import {
6
+ JsonEventSerializer,
7
+ JsonSnapshotSerializer,
8
+ } from "./internal/default-serializer";
9
+ import { EventStoreForDynamoDB } from "./internal/event-store-for-dynamodb";
10
+ import { EventStoreForMemory } from "./internal/event-store-for-memory";
11
+ import type {
2
12
  Aggregate,
3
13
  AggregateId,
4
14
  Event,
@@ -7,16 +17,6 @@ import {
7
17
  Logger,
8
18
  SnapshotSerializer,
9
19
  } from "./types";
10
- import { EventStoreForDynamoDB } from "./internal/event-store-for-dynamodb";
11
- import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
12
- import moment from "moment";
13
- import { DefaultKeyResolver } from "./internal/default-key-resolver";
14
- import {
15
- JsonEventSerializer,
16
- JsonSnapshotSerializer,
17
- } from "./internal/default-serializer";
18
- import { EventStoreForMemory } from "./internal/event-store-for-memory";
19
- import { EventStoreWithOptions } from "./event-store-with-options";
20
20
 
21
21
  interface EventStore<
22
22
  AID extends AggregateId,
@@ -88,4 +88,4 @@ class EventStoreFactory {
88
88
  }
89
89
  }
90
90
 
91
- export { EventStore, EventStoreFactory };
91
+ export { type EventStore, EventStoreFactory };
@@ -1,4 +1,4 @@
1
- import { AggregateId, KeyResolver } from "../types";
1
+ import type { AggregateId, KeyResolver } from "../types";
2
2
 
3
3
  class DefaultKeyResolver<AID extends AggregateId> implements KeyResolver<AID> {
4
4
  private hashString(str: string): number {
@@ -1,4 +1,4 @@
1
- import {
1
+ import type {
2
2
  Aggregate,
3
3
  AggregateId,
4
4
  Event,
@@ -12,7 +12,7 @@ class JsonEventSerializer<AID extends AggregateId, E extends Event<AID>>
12
12
  private encoder = new TextEncoder();
13
13
  private decoder = new TextDecoder();
14
14
 
15
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ // biome-ignore lint/suspicious/noExplicitAny:
16
16
  deserialize(bytes: Uint8Array, converter: (json: any) => E): E {
17
17
  const jsonString = this.decoder.decode(bytes);
18
18
  const json = JSON.parse(jsonString);
@@ -35,7 +35,7 @@ class JsonSnapshotSerializer<
35
35
  {
36
36
  private encoder = new TextEncoder();
37
37
  private decoder = new TextDecoder();
38
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ // biome-ignore lint/suspicious/noExplicitAny:
39
39
  deserialize(bytes: Uint8Array, converter: (json: any) => A): A {
40
40
  const jsonString = this.decoder.decode(bytes);
41
41
  const obj = JSON.parse(jsonString);
@@ -1,31 +1,33 @@
1
+ import { describe } from "node:test";
2
+ import type { DynamoDBClient } from "@aws-sdk/client-dynamodb";
1
3
  import {
2
4
  GenericContainer,
3
- StartedTestContainer,
4
- TestContainer,
5
+ type StartedTestContainer,
6
+ type TestContainer,
5
7
  Wait,
6
8
  } from "testcontainers";
7
- import { describe } from "node:test";
8
- import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
9
- import { EventStoreForDynamoDB } from "./event-store-for-dynamodb";
10
9
  import { ulid } from "ulid";
11
- import { UserAccountId } from "./test/user-account-id";
12
- import { convertJSONToUserAccount, UserAccount } from "./test/user-account";
13
- import {
14
- convertJSONtoUserAccountEvent,
15
- UserAccountEvent,
16
- } from "./test/user-account-event";
10
+ import { EventStoreForDynamoDB } from "./event-store-for-dynamodb";
17
11
  import {
18
12
  createDynamoDBClient,
19
13
  createJournalTable,
20
14
  createSnapshotTable,
21
15
  } from "./test/dynamodb-utils";
16
+ import { UserAccount, convertJSONToUserAccount } from "./test/user-account";
17
+ import {
18
+ type UserAccountEvent,
19
+ convertJSONtoUserAccountEvent,
20
+ } from "./test/user-account-event";
21
+ import { UserAccountId } from "./test/user-account-id";
22
22
 
23
23
  afterEach(() => {
24
24
  jest.useRealTimers();
25
25
  });
26
26
 
27
27
  describe("EventStoreForDynamoDB", () => {
28
- const TEST_TIME_FACTOR = parseFloat(process.env.TEST_TIME_FACTOR ?? "1.0");
28
+ const TEST_TIME_FACTOR = Number.parseFloat(
29
+ process.env.TEST_TIME_FACTOR ?? "1.0",
30
+ );
29
31
  const TIMEOUT: number = 10 * 1000 * TEST_TIME_FACTOR;
30
32
 
31
33
  let container: TestContainer;
@@ -1,34 +1,34 @@
1
- import {
2
- Aggregate,
3
- AggregateId,
4
- Event,
5
- EventSerializer,
6
- KeyResolver,
7
- Logger,
8
- OptimisticLockError,
9
- SnapshotSerializer,
10
- } from "../types";
11
1
  import {
12
2
  BatchWriteItemCommand,
13
- DynamoDBClient,
14
- Put,
3
+ type DynamoDBClient,
4
+ type Put,
15
5
  QueryCommand,
16
- QueryCommandInput,
17
- TransactionCanceledException,
6
+ type QueryCommandInput,
18
7
  TransactWriteItemsCommand,
19
- TransactWriteItemsInput,
20
- Update,
8
+ type TransactWriteItemsInput,
9
+ TransactionCanceledException,
10
+ type Update,
21
11
  UpdateItemCommand,
22
- UpdateItemInput,
23
- WriteRequest,
12
+ type UpdateItemInput,
13
+ type WriteRequest,
24
14
  } from "@aws-sdk/client-dynamodb";
25
15
  import moment from "moment/moment";
16
+ import type { EventStoreWithOptions } from "../event-store-with-options";
17
+ import {
18
+ type Aggregate,
19
+ type AggregateId,
20
+ type Event,
21
+ type EventSerializer,
22
+ type KeyResolver,
23
+ type Logger,
24
+ OptimisticLockError,
25
+ type SnapshotSerializer,
26
+ } from "../types";
26
27
  import { DefaultKeyResolver } from "./default-key-resolver";
27
28
  import {
28
29
  JsonEventSerializer,
29
30
  JsonSnapshotSerializer,
30
31
  } from "./default-serializer";
31
- import { EventStoreWithOptions } from "../event-store-with-options";
32
32
 
33
33
  class EventStoreForDynamoDB<
34
34
  AID extends AggregateId,
@@ -131,25 +131,24 @@ class EventStoreForDynamoDB<
131
131
  );
132
132
  if (queryResult.Items === undefined || queryResult.Items.length === 0) {
133
133
  return undefined;
134
- } else {
135
- const item = queryResult.Items[0];
136
- const version = item.version.N;
137
- if (version === undefined) {
138
- throw new Error("Version is undefined");
139
- }
140
- const payload = item.payload.B;
141
- if (payload === undefined) {
142
- throw new Error("Payload is undefined");
143
- }
144
- const result = this.snapshotSerializer.deserialize(
145
- payload,
146
- this.snapshotConverter,
147
- );
148
- this.logger?.debug(
149
- `getLatestSnapshotById(${JSON.stringify(id)}, ...): finished`,
150
- );
151
- return result.withVersion(Number(version));
152
134
  }
135
+ const item = queryResult.Items[0];
136
+ const version = item.version.N;
137
+ if (version === undefined) {
138
+ throw new Error("Version is undefined");
139
+ }
140
+ const payload = item.payload.B;
141
+ if (payload === undefined) {
142
+ throw new Error("Payload is undefined");
143
+ }
144
+ const result = this.snapshotSerializer.deserialize(
145
+ payload,
146
+ this.snapshotConverter,
147
+ );
148
+ this.logger?.debug(
149
+ `getLatestSnapshotById(${JSON.stringify(id)}, ...): finished`,
150
+ );
151
+ return result.withVersion(Number(version));
153
152
  }
154
153
 
155
154
  async persistEvent(event: E, version: number): Promise<void> {
@@ -336,14 +335,13 @@ class EventStoreForDynamoDB<
336
335
  } catch (e) {
337
336
  if (
338
337
  e instanceof TransactionCanceledException &&
339
- e.CancellationReasons?.some((e) => e.Code == "ConditionalCheckFailed")
338
+ e.CancellationReasons?.some((e) => e.Code === "ConditionalCheckFailed")
340
339
  ) {
341
340
  throw new OptimisticLockError("Optimistic locking failed", e);
342
- } else {
343
- throw e;
344
341
  }
342
+ throw e;
345
343
  }
346
- this.logger?.debug(`private createEventAndSnapshot(...): finished`);
344
+ this.logger?.debug("private createEventAndSnapshot(...): finished");
347
345
  }
348
346
 
349
347
  private async updateEventAndSnapshotOpt(
@@ -374,14 +372,13 @@ class EventStoreForDynamoDB<
374
372
  } catch (e) {
375
373
  if (
376
374
  e instanceof TransactionCanceledException &&
377
- e.CancellationReasons?.some((e) => e.Code == "ConditionalCheckFailed")
375
+ e.CancellationReasons?.some((e) => e.Code === "ConditionalCheckFailed")
378
376
  ) {
379
377
  throw new OptimisticLockError("Optimistic locking failed", e);
380
- } else {
381
- throw e;
382
378
  }
379
+ throw e;
383
380
  }
384
- this.logger?.debug(`private updateEventAndSnapshotOpt(...): finished`);
381
+ this.logger?.debug("private updateEventAndSnapshotOpt(...): finished");
385
382
  }
386
383
 
387
384
  private putJournal(event: E): Put {
@@ -408,7 +405,7 @@ class EventStoreForDynamoDB<
408
405
  ConditionExpression:
409
406
  "attribute_not_exists(pkey) AND attribute_not_exists(skey)",
410
407
  };
411
- this.logger?.debug(`private putSnapshot(...): finished`);
408
+ this.logger?.debug("private putSnapshot(...): finished");
412
409
  return result;
413
410
  }
414
411
 
@@ -444,8 +441,8 @@ class EventStoreForDynamoDB<
444
441
  ConditionExpression:
445
442
  "attribute_not_exists(pkey) AND attribute_not_exists(skey)",
446
443
  };
447
- this.logger?.debug("result = " + JSON.stringify(result));
448
- this.logger?.debug(`private putSnapshot(...): finished`);
444
+ this.logger?.debug(`result = ${JSON.stringify(result)}`);
445
+ this.logger?.debug("private putSnapshot(...): finished");
449
446
  return result;
450
447
  }
451
448
 
@@ -514,8 +511,8 @@ class EventStoreForDynamoDB<
514
511
  ConditionExpression: "#version=:before_version",
515
512
  };
516
513
  }
517
- this.logger?.debug("result = " + JSON.stringify(result));
518
- this.logger?.debug(`private updateSnapshot(...): finished`);
514
+ this.logger?.debug(`result·=·${JSON.stringify(result)}`);
515
+ this.logger?.debug("private·updateSnapshot(...)finished");
519
516
  return result;
520
517
  }
521
518
 
@@ -582,16 +579,15 @@ class EventStoreForDynamoDB<
582
579
  );
583
580
  if (queryResult.Items === undefined || queryResult.Items.length === 0) {
584
581
  return undefined;
585
- } else {
586
- return queryResult.Items.map((item) => {
587
- const pkey = item.pkey.S;
588
- const skey = item.skey.S;
589
- if (pkey === undefined || skey === undefined) {
590
- throw new Error("pkey or skey is undefined");
591
- }
592
- return { pkey, skey };
593
- });
594
582
  }
583
+ return queryResult.Items.map((item) => {
584
+ const pkey = item.pkey.S;
585
+ const skey = item.skey.S;
586
+ if (pkey === undefined || skey === undefined) {
587
+ throw new Error("pkey or skey is undefined");
588
+ }
589
+ return { pkey, skey };
590
+ });
595
591
  }
596
592
 
597
593
  private async updateTtlOfExcessSnapshots(aggregateId: AID) {
@@ -1,16 +1,18 @@
1
1
  import { describe } from "node:test";
2
- import { UserAccountId } from "./test/user-account-id";
3
- import { UserAccount } from "./test/user-account";
4
- import { UserAccountEvent } from "./test/user-account-event";
5
- import { EventStore, EventStoreFactory } from "../event-store";
6
2
  import { ulid } from "ulid";
3
+ import { type EventStore, EventStoreFactory } from "../event-store";
4
+ import { UserAccount } from "./test/user-account";
5
+ import type { UserAccountEvent } from "./test/user-account-event";
6
+ import { UserAccountId } from "./test/user-account-id";
7
7
 
8
8
  afterEach(() => {
9
9
  jest.useRealTimers();
10
10
  });
11
11
 
12
12
  describe("EventStoreForDynamoDB", () => {
13
- const TEST_TIME_FACTOR = parseFloat(process.env.TEST_TIME_FACTOR ?? "1.0");
13
+ const TEST_TIME_FACTOR = Number.parseFloat(
14
+ process.env.TEST_TIME_FACTOR ?? "1.0",
15
+ );
14
16
  const TIMEOUT: number = 10 * 1000 * TEST_TIME_FACTOR;
15
17
 
16
18
  let eventStore: EventStore<UserAccountId, UserAccount, UserAccountEvent>;
@@ -1,5 +1,5 @@
1
- import { Aggregate, AggregateId, Event } from "../types";
2
- import { EventStore } from "../event-store";
1
+ import type { EventStore } from "../event-store";
2
+ import type { Aggregate, AggregateId, Event } from "../types";
3
3
 
4
4
  class EventStoreForMemory<
5
5
  AID extends AggregateId,
@@ -37,10 +37,7 @@ class EventStoreForMemory<
37
37
  }
38
38
  if (snapshot.id.asString() !== event.aggregateId.asString()) {
39
39
  throw new Error(
40
- "aggregateId mismatch: snapshot.id = " +
41
- snapshot.id.asString() +
42
- ", event.aggregateId = " +
43
- event.aggregateId.asString(),
40
+ `aggregateId·mismatchsnapshot.id·=·${snapshot.id.asString()},·event.aggregateId·=·${event.aggregateId.asString()}`,
44
41
  );
45
42
  }
46
43
  if (snapshot.version !== version) {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  CreateTableCommand,
3
- CreateTableCommandInput,
3
+ type CreateTableCommandInput,
4
4
  DynamoDBClient,
5
5
  } from "@aws-sdk/client-dynamodb";
6
- import { StartedTestContainer } from "testcontainers";
6
+ import type { StartedTestContainer } from "testcontainers";
7
7
 
8
8
  function createDynamoDBClient(startedContainer: StartedTestContainer) {
9
9
  const port = startedContainer.getMappedPort(4566);
@@ -1,5 +1,8 @@
1
- import { Event } from "../../types";
2
- import { convertJSONToUserAccountId, UserAccountId } from "./user-account-id";
1
+ import type { Event } from "../../types";
2
+ import {
3
+ type UserAccountId,
4
+ convertJSONToUserAccountId,
5
+ } from "./user-account-id";
3
6
 
4
7
  interface UserAccountEvent extends Event<UserAccountId> {}
5
8
 
@@ -28,7 +31,7 @@ class UserAccountRenamed implements UserAccountEvent {
28
31
  ) {}
29
32
  }
30
33
 
31
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ // biome-ignore lint/suspicious/noExplicitAny:
32
35
  function convertJSONtoUserAccountEvent(json: any): UserAccountEvent {
33
36
  const aggregateId = convertJSONToUserAccountId(json.data.aggregateId);
34
37
  switch (json.type) {
@@ -54,7 +57,7 @@ function convertJSONtoUserAccountEvent(json: any): UserAccountEvent {
54
57
  }
55
58
 
56
59
  export {
57
- UserAccountEvent,
60
+ type UserAccountEvent,
58
61
  UserAccountCreated,
59
62
  UserAccountRenamed,
60
63
  convertJSONtoUserAccountEvent,
@@ -1,4 +1,4 @@
1
- import { AggregateId } from "../../types";
1
+ import type { AggregateId } from "../../types";
2
2
 
3
3
  class UserAccountId implements AggregateId {
4
4
  public readonly typeName = "user-account";
@@ -9,7 +9,7 @@ class UserAccountId implements AggregateId {
9
9
  }
10
10
  }
11
11
 
12
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ // biome-ignore lint/suspicious/noExplicitAny:
13
13
  function convertJSONToUserAccountId(json: any): UserAccountId {
14
14
  return new UserAccountId(json.value);
15
15
  }
@@ -1,32 +1,34 @@
1
1
  import { describe } from "node:test";
2
+ import type { DynamoDBClient } from "@aws-sdk/client-dynamodb";
2
3
  import {
3
4
  GenericContainer,
4
- StartedTestContainer,
5
- TestContainer,
5
+ type StartedTestContainer,
6
+ type TestContainer,
6
7
  Wait,
7
8
  } from "testcontainers";
8
- import { UserAccountId } from "./user-account-id";
9
- import { convertJSONToUserAccount, UserAccount } from "./user-account";
10
- import {
11
- convertJSONtoUserAccountEvent,
12
- UserAccountEvent,
13
- } from "./user-account-event";
14
- import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
9
+ import { ulid } from "ulid";
10
+ import { type EventStore, EventStoreFactory } from "../../event-store";
15
11
  import {
16
12
  createDynamoDBClient,
17
13
  createJournalTable,
18
14
  createSnapshotTable,
19
15
  } from "./dynamodb-utils";
20
- import { ulid } from "ulid";
16
+ import { UserAccount, convertJSONToUserAccount } from "./user-account";
17
+ import {
18
+ type UserAccountEvent,
19
+ convertJSONtoUserAccountEvent,
20
+ } from "./user-account-event";
21
+ import { UserAccountId } from "./user-account-id";
21
22
  import { UserAccountRepository } from "./user-account-repository";
22
- import { EventStore, EventStoreFactory } from "../../event-store";
23
23
 
24
24
  afterEach(() => {
25
25
  jest.useRealTimers();
26
26
  });
27
27
 
28
28
  describe("UserAccountRepository", () => {
29
- const TEST_TIME_FACTOR = parseFloat(process.env.TEST_TIME_FACTOR ?? "1.0");
29
+ const TEST_TIME_FACTOR = Number.parseFloat(
30
+ process.env.TEST_TIME_FACTOR ?? "1.0",
31
+ );
30
32
  const TIMEOUT: number = 10 * 1000 * TEST_TIME_FACTOR;
31
33
 
32
34
  let container: TestContainer;
@@ -1,7 +1,7 @@
1
- import { UserAccountEvent } from "./user-account-event";
2
- import { UserAccountId } from "./user-account-id";
1
+ import type { EventStore } from "../../event-store";
3
2
  import { UserAccount } from "./user-account";
4
- import { EventStore } from "../../event-store";
3
+ import type { UserAccountEvent } from "./user-account-event";
4
+ import type { UserAccountId } from "./user-account-id";
5
5
 
6
6
  class UserAccountRepository {
7
7
  constructor(
@@ -24,13 +24,12 @@ class UserAccountRepository {
24
24
  const snapshot = await this.eventStore.getLatestSnapshotById(id);
25
25
  if (snapshot === undefined) {
26
26
  return undefined;
27
- } else {
28
- const events = await this.eventStore.getEventsByIdSinceSequenceNumber(
29
- id,
30
- snapshot.sequenceNumber + 1,
31
- );
32
- return UserAccount.replay(events, snapshot);
33
27
  }
28
+ const events = await this.eventStore.getEventsByIdSinceSequenceNumber(
29
+ id,
30
+ snapshot.sequenceNumber + 1,
31
+ );
32
+ return UserAccount.replay(events, snapshot);
34
33
  }
35
34
  }
36
35
 
@@ -1,11 +1,14 @@
1
- import { Aggregate } from "../../types";
2
1
  import { ulid } from "ulid";
3
- import { convertJSONToUserAccountId, UserAccountId } from "./user-account-id";
2
+ import type { Aggregate } from "../../types";
4
3
  import {
5
4
  UserAccountCreated,
6
- UserAccountEvent,
5
+ type UserAccountEvent,
7
6
  UserAccountRenamed,
8
7
  } from "./user-account-event";
8
+ import {
9
+ type UserAccountId,
10
+ convertJSONToUserAccountId,
11
+ } from "./user-account-id";
9
12
 
10
13
  class UserAccount implements Aggregate<UserAccount, UserAccountId> {
11
14
  public readonly typeName: string = "UserAccount";
@@ -87,13 +90,12 @@ class UserAccount implements Aggregate<UserAccount, UserAccountId> {
87
90
  if (event instanceof UserAccountRenamed) {
88
91
  const [result] = this.rename(event.name);
89
92
  return result;
90
- } else {
91
- throw new Error("Unknown event type");
92
93
  }
94
+ throw new Error("Unknown event type");
93
95
  }
94
96
  }
95
97
 
96
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
98
+ // biome-ignore lint/suspicious/noExplicitAny:
97
99
  function convertJSONToUserAccount(json: any): UserAccount {
98
100
  const id = convertJSONToUserAccountId(json.data.id);
99
101
  return new UserAccount(
package/src/types.ts CHANGED
@@ -33,7 +33,7 @@ interface KeyResolver<AID extends AggregateId> {
33
33
 
34
34
  interface EventSerializer<AID extends AggregateId, E extends Event<AID>> {
35
35
  serialize(event: E): Uint8Array;
36
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
+ // biome-ignore lint/suspicious/noExplicitAny:
37
37
  deserialize(bytes: Uint8Array, converter: (json: any) => E): E;
38
38
  }
39
39
 
@@ -42,20 +42,20 @@ interface SnapshotSerializer<
42
42
  A extends Aggregate<A, AID>,
43
43
  > {
44
44
  serialize(aggregate: A): Uint8Array;
45
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
+ // biome-ignore lint/suspicious/noExplicitAny:
46
46
  deserialize(bytes: Uint8Array, converter: (json: any) => A): A;
47
47
  }
48
48
 
49
49
  export interface Logger {
50
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
+ // biome-ignore lint/suspicious/noExplicitAny:
51
51
  trace?: (...content: any[]) => void;
52
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
+ // biome-ignore lint/suspicious/noExplicitAny:
53
53
  debug: (...content: any[]) => void;
54
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
+ // biome-ignore lint/suspicious/noExplicitAny:
55
55
  info: (...content: any[]) => void;
56
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
56
+ // biome-ignore lint/suspicious/noExplicitAny:
57
57
  warn: (...content: any[]) => void;
58
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
58
+ // biome-ignore lint/suspicious/noExplicitAny:
59
59
  error: (...content: any[]) => void;
60
60
  }
61
61
 
@@ -71,11 +71,11 @@ class OptimisticLockError extends Error {
71
71
  }
72
72
 
73
73
  export {
74
- AggregateId,
75
- Aggregate,
76
- Event,
77
- KeyResolver,
78
- EventSerializer,
79
- SnapshotSerializer,
74
+ type AggregateId,
75
+ type Aggregate,
76
+ type Event,
77
+ type KeyResolver,
78
+ type EventSerializer,
79
+ type SnapshotSerializer,
80
80
  OptimisticLockError,
81
81
  };
package/.eslintrc.cjs DELETED
@@ -1,25 +0,0 @@
1
- module.exports = {
2
- rules: {
3
- },
4
- reportUnusedDisableDirectives: true,
5
- ignorePatterns: ["dist/*"],
6
- env: { browser: true, es2020: true, node: true },
7
- parserOptions: { ecmaVersion: "latest", sourceType: "module" },
8
- settings: { react: { version: "detect" } },
9
- plugins: [],
10
- extends: [
11
- "eslint:recommended",
12
- ],
13
- overrides: [
14
- {
15
- files: ["*.ts", "*.tsx"],
16
- parser: "@typescript-eslint/parser",
17
- plugins: ["@typescript-eslint"],
18
- extends: ["plugin:@typescript-eslint/recommended"],
19
- rules: {
20
- // TypeScriptに関するカスタムルールをここに追加できます
21
- "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
22
- },
23
- },
24
- ],
25
- };
package/.prettierignore DELETED
@@ -1,2 +0,0 @@
1
- dist/
2
- node_modules/
package/.prettierrc.yml DELETED
@@ -1,3 +0,0 @@
1
- tabWidth: 2
2
- semi: true
3
- singleQuote: false