@arts-n-crafts/ts 3.15.0 → 3.17.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/package.json +59 -32
- package/{dist → packages/v3/dist}/index.cjs +35 -35
- package/packages/v3/dist/index.cjs.map +1 -0
- package/{dist → packages/v3/dist}/index.d.cts +31 -40
- package/{dist → packages/v3/dist}/index.d.ts +31 -40
- package/{dist → packages/v3/dist}/index.js +35 -35
- package/packages/v3/dist/index.js.map +1 -0
- package/packages/v3/package.json +52 -0
- package/packages/v4/dist/index.cjs +586 -0
- package/packages/v4/dist/index.cjs.map +1 -0
- package/packages/v4/dist/index.d.cts +575 -0
- package/packages/v4/dist/index.d.ts +575 -0
- package/packages/v4/dist/index.js +551 -0
- package/packages/v4/dist/index.js.map +1 -0
- package/packages/v4/package.json +52 -0
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arts-n-crafts/ts",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.17.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/arts-n-crafts/typescript.git"
|
|
@@ -13,58 +13,85 @@
|
|
|
13
13
|
"main": "./dist/index.cjs",
|
|
14
14
|
"module": "./dist/index.js",
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@antfu/eslint-config": "^
|
|
16
|
+
"@antfu/eslint-config": "^6.7.3",
|
|
17
17
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
18
|
-
"@commitlint/cli": "^
|
|
19
|
-
"@commitlint/config-conventional": "^
|
|
20
|
-
"@eslint/js": "^9.
|
|
18
|
+
"@commitlint/cli": "^20.2.0",
|
|
19
|
+
"@commitlint/config-conventional": "^20.2.0",
|
|
20
|
+
"@eslint/js": "^9.39.2",
|
|
21
21
|
"@release-it/bumper": "^7.0.5",
|
|
22
|
-
"@stylistic/eslint-plugin": "^5.
|
|
23
|
-
"@types/bun": "^1.
|
|
24
|
-
"@vitest/coverage-istanbul": "^
|
|
25
|
-
"@vitest/ui": "^
|
|
22
|
+
"@stylistic/eslint-plugin": "^5.6.1",
|
|
23
|
+
"@types/bun": "^1.3.5",
|
|
24
|
+
"@vitest/coverage-istanbul": "^4.0.16",
|
|
25
|
+
"@vitest/ui": "^4.0.16",
|
|
26
26
|
"changelogen": "^0.6.2",
|
|
27
27
|
"commitizen": "^4.3.1",
|
|
28
28
|
"cz-conventional-changelog": "^3.3.0",
|
|
29
|
-
"eslint": "^9.
|
|
30
|
-
"globals": "^16.
|
|
29
|
+
"eslint": "^9.39.2",
|
|
30
|
+
"globals": "^16.5.0",
|
|
31
31
|
"husky": "^9.1.7",
|
|
32
32
|
"oxide.ts": "^1.1.0",
|
|
33
|
-
"release-it": "^19.0
|
|
33
|
+
"release-it": "^19.1.0",
|
|
34
34
|
"release-it-changelogen": "^0.1.0",
|
|
35
|
-
"rimraf": "^6.
|
|
36
|
-
"tsup": "^8.5.
|
|
37
|
-
"typescript-eslint": "^8.
|
|
38
|
-
"vite-tsconfig-paths": "^
|
|
39
|
-
"vitest": "^
|
|
35
|
+
"rimraf": "^6.1.2",
|
|
36
|
+
"tsup": "^8.5.1",
|
|
37
|
+
"typescript-eslint": "^8.50.0",
|
|
38
|
+
"vite-tsconfig-paths": "^6.0.3",
|
|
39
|
+
"vitest": "^4.0.16"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"typescript": "^5.
|
|
42
|
+
"typescript": "^5.9.3"
|
|
43
43
|
},
|
|
44
44
|
"exports": {
|
|
45
|
-
"./package.json": "./package.json",
|
|
46
45
|
".": {
|
|
47
|
-
"import":
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
"import": {
|
|
47
|
+
"types": "./packages/v3/dist/index.d.ts",
|
|
48
|
+
"default": "./packages/v3/dist/index.js"
|
|
49
|
+
},
|
|
50
|
+
"require": {
|
|
51
|
+
"types": "./packages/v3/dist/index.d.cts",
|
|
52
|
+
"default": "./packages/v3/dist/index.cjs"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"./v3": {
|
|
56
|
+
"import": {
|
|
57
|
+
"types": "./packages/v3/dist/index.d.ts",
|
|
58
|
+
"default": "./packages/v3/dist/index.js"
|
|
59
|
+
},
|
|
60
|
+
"require": {
|
|
61
|
+
"types": "./packages/v3/dist/index.d.cts",
|
|
62
|
+
"default": "./packages/v3/dist/index.cjs"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"./v4": {
|
|
66
|
+
"import": {
|
|
67
|
+
"types": "./packages/v4/dist/index.d.ts",
|
|
68
|
+
"default": "./packages/v4/dist/index.js"
|
|
69
|
+
},
|
|
70
|
+
"require": {
|
|
71
|
+
"types": "./packages/v4/dist/index.d.cts",
|
|
72
|
+
"default": "./packages/v4/dist/index.cjs"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"./package.json": "./package.json"
|
|
50
76
|
},
|
|
51
77
|
"files": [
|
|
52
|
-
"dist"
|
|
78
|
+
"packages/v3/dist",
|
|
79
|
+
"packages/v4/dist",
|
|
80
|
+
"package.json",
|
|
81
|
+
"README.md",
|
|
82
|
+
"LICENSE"
|
|
53
83
|
],
|
|
54
84
|
"private": false,
|
|
55
85
|
"scripts": {
|
|
56
86
|
"prepare": "husky",
|
|
57
87
|
"commit": "cz",
|
|
58
|
-
"lint": "eslint src/",
|
|
59
|
-
"lint:fix": "eslint --fix src/",
|
|
60
|
-
"test": "NODE_ENV=test vitest",
|
|
61
|
-
"test:watch": "NODE_ENV=test vitest --coverage --watch",
|
|
62
|
-
"test:ui": "NODE_ENV=test vitest --watch --coverage --ui",
|
|
63
|
-
"coverage": "NODE_ENV=test vitest --coverage",
|
|
64
|
-
"typecheck": "tsc --noEmit",
|
|
65
88
|
"release": "release-it && npm publish --access=public",
|
|
66
|
-
"build": "
|
|
67
|
-
"
|
|
89
|
+
"build": "bun run --workspaces build",
|
|
90
|
+
"coverage": "bun run --workspaces coverage",
|
|
91
|
+
"lint": "bun run --workspaces lint",
|
|
92
|
+
"lint:fix": "bun run --workspaces lint:fix",
|
|
93
|
+
"typecheck": "bun run --workspaces typecheck",
|
|
94
|
+
"check-exports": "attw --pack . --profile node16"
|
|
68
95
|
},
|
|
69
96
|
"type": "module"
|
|
70
97
|
}
|
|
@@ -48,7 +48,7 @@ function isQuery(candidate) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
// src/domain/Specification/Specification.ts
|
|
51
|
-
var
|
|
51
|
+
var Specification = class {
|
|
52
52
|
and(other) {
|
|
53
53
|
return new AndSpecification(this, other);
|
|
54
54
|
}
|
|
@@ -59,7 +59,7 @@ var CompositeSpecification = class {
|
|
|
59
59
|
return new NotSpecification(this);
|
|
60
60
|
}
|
|
61
61
|
};
|
|
62
|
-
var AndSpecification = class extends
|
|
62
|
+
var AndSpecification = class extends Specification {
|
|
63
63
|
constructor(left, right) {
|
|
64
64
|
super();
|
|
65
65
|
this.left = left;
|
|
@@ -75,7 +75,7 @@ var AndSpecification = class extends CompositeSpecification {
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
};
|
|
78
|
-
var OrSpecification = class extends
|
|
78
|
+
var OrSpecification = class extends Specification {
|
|
79
79
|
constructor(left, right) {
|
|
80
80
|
super();
|
|
81
81
|
this.left = left;
|
|
@@ -91,7 +91,7 @@ var OrSpecification = class extends CompositeSpecification {
|
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
93
|
};
|
|
94
|
-
var NotSpecification = class extends
|
|
94
|
+
var NotSpecification = class extends Specification {
|
|
95
95
|
constructor(spec) {
|
|
96
96
|
super();
|
|
97
97
|
this.spec = spec;
|
|
@@ -123,7 +123,7 @@ function createQueryNode(type, field, value) {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
// src/domain/Specification/implementations/FieldEquals.specification.ts
|
|
126
|
-
var FieldEquals = class extends
|
|
126
|
+
var FieldEquals = class extends Specification {
|
|
127
127
|
constructor(field, value) {
|
|
128
128
|
super();
|
|
129
129
|
this.field = field;
|
|
@@ -151,7 +151,7 @@ function invariant(condition, onInvalid) {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
// src/domain/Specification/implementations/FieldGreaterThan.specification.ts
|
|
154
|
-
var FieldGreaterThan = class extends
|
|
154
|
+
var FieldGreaterThan = class extends Specification {
|
|
155
155
|
constructor(field, value) {
|
|
156
156
|
super();
|
|
157
157
|
this.field = field;
|
|
@@ -181,7 +181,7 @@ function createDomainEvent(type, aggregateId, payload, metadata = {}) {
|
|
|
181
181
|
aggregateId,
|
|
182
182
|
payload,
|
|
183
183
|
source: "internal",
|
|
184
|
-
timestamp:
|
|
184
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
185
185
|
metadata
|
|
186
186
|
});
|
|
187
187
|
}
|
|
@@ -336,31 +336,6 @@ function isIntegrationEvent(event) {
|
|
|
336
336
|
return isEvent(event) && event.source === "external";
|
|
337
337
|
}
|
|
338
338
|
|
|
339
|
-
// src/utils/isEqual/isEqual.ts
|
|
340
|
-
function isEqual(a, b) {
|
|
341
|
-
if (a === b) {
|
|
342
|
-
return true;
|
|
343
|
-
}
|
|
344
|
-
const bothAreObjects = a && b && typeof a === "object" && typeof b === "object";
|
|
345
|
-
return Boolean(
|
|
346
|
-
bothAreObjects && Object.keys(a).length === Object.keys(b).length && Object.entries(a).every(([k, v]) => isEqual(v, b[k]))
|
|
347
|
-
);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// src/utils/parseAsError/parseAsError.ts
|
|
351
|
-
function parseAsError(value) {
|
|
352
|
-
if (value instanceof Error)
|
|
353
|
-
return value;
|
|
354
|
-
if (typeof value === "string")
|
|
355
|
-
return new Error(value);
|
|
356
|
-
try {
|
|
357
|
-
const json = JSON.stringify(value);
|
|
358
|
-
return new Error(json ?? String(value));
|
|
359
|
-
} catch {
|
|
360
|
-
return new Error("Unknown error");
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
339
|
// src/utils/streamKey/makeStreamKey.ts
|
|
365
340
|
function makeStreamKey(streamName, aggregateId) {
|
|
366
341
|
return `${streamName}#${aggregateId}`;
|
|
@@ -372,7 +347,7 @@ function createStoredEvent(streamName, version, event) {
|
|
|
372
347
|
id: event.id,
|
|
373
348
|
streamKey: makeStreamKey(streamName, event.aggregateId),
|
|
374
349
|
version,
|
|
375
|
-
|
|
350
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
376
351
|
event
|
|
377
352
|
});
|
|
378
353
|
}
|
|
@@ -522,6 +497,17 @@ var SimpleRepository = class {
|
|
|
522
497
|
}
|
|
523
498
|
};
|
|
524
499
|
|
|
500
|
+
// src/utils/isEqual/isEqual.ts
|
|
501
|
+
function isEqual(a, b) {
|
|
502
|
+
if (a === b) {
|
|
503
|
+
return true;
|
|
504
|
+
}
|
|
505
|
+
const bothAreObjects = a && b && typeof a === "object" && typeof b === "object";
|
|
506
|
+
return Boolean(
|
|
507
|
+
bothAreObjects && Object.keys(a).length === Object.keys(b).length && Object.entries(a).every(([k, v]) => isEqual(v, b[k]))
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
|
|
525
511
|
// src/infrastructure/ScenarioTest/ScenarioTest.ts
|
|
526
512
|
var ScenarioTest = class {
|
|
527
513
|
constructor(streamName, eventBus, eventStore, commandBus, queryBus, repository, outboxWorker) {
|
|
@@ -553,7 +539,7 @@ var ScenarioTest = class {
|
|
|
553
539
|
const integrationEvents = this.givenInput.filter(isIntegrationEvent);
|
|
554
540
|
await Promise.all([
|
|
555
541
|
this.repository.store(domainEvents),
|
|
556
|
-
integrationEvents.map(async (event) => this.eventBus.consume(this.streamName, event))
|
|
542
|
+
...integrationEvents.map(async (event) => this.eventBus.consume(this.streamName, event))
|
|
557
543
|
]);
|
|
558
544
|
if (!this.whenInput) {
|
|
559
545
|
throw new Error("In the ScenarioTest, the when-step cannot be empty");
|
|
@@ -622,8 +608,21 @@ var ScenarioTest = class {
|
|
|
622
608
|
}
|
|
623
609
|
};
|
|
624
610
|
|
|
611
|
+
// src/utils/parseAsError/parseAsError.ts
|
|
612
|
+
function parseAsError(value) {
|
|
613
|
+
if (value instanceof Error)
|
|
614
|
+
return value;
|
|
615
|
+
if (typeof value === "string")
|
|
616
|
+
return new Error(value);
|
|
617
|
+
try {
|
|
618
|
+
const json = JSON.stringify(value);
|
|
619
|
+
return new Error(json ?? String(value));
|
|
620
|
+
} catch {
|
|
621
|
+
return new Error("Unknown error");
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
625
|
exports.AndSpecification = AndSpecification;
|
|
626
|
-
exports.CompositeSpecification = CompositeSpecification;
|
|
627
626
|
exports.FieldEquals = FieldEquals;
|
|
628
627
|
exports.FieldGreaterThan = FieldGreaterThan;
|
|
629
628
|
exports.GenericOutboxWorker = GenericOutboxWorker;
|
|
@@ -638,6 +637,7 @@ exports.SimpleEventBus = SimpleEventBus;
|
|
|
638
637
|
exports.SimpleEventStore = SimpleEventStore;
|
|
639
638
|
exports.SimpleQueryBus = SimpleQueryBus;
|
|
640
639
|
exports.SimpleRepository = SimpleRepository;
|
|
640
|
+
exports.Specification = Specification;
|
|
641
641
|
exports.createCommand = createCommand;
|
|
642
642
|
exports.createDomainEvent = createDomainEvent;
|
|
643
643
|
exports.createIntegrationEvent = createIntegrationEvent;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/utils/createCommand.ts","../src/core/utils/createQuery.ts","../src/core/utils/isCommand.ts","../src/core/utils/isQuery.ts","../src/domain/Specification/Specification.ts","../src/domain/Specification/utils/createQueryNode.ts","../src/domain/Specification/implementations/FieldEquals.specification.ts","../src/utils/fail/fail.ts","../src/utils/invariant/invariant.ts","../src/domain/Specification/implementations/FieldGreaterThan.specification.ts","../src/domain/utils/createDomainEvent.ts","../src/domain/utils/isEvent.ts","../src/domain/utils/isDomainEvent.ts","../src/infrastructure/CommandBus/implementations/SimpleCommandBus.ts","../src/infrastructure/Database/Database.ts","../src/infrastructure/Database/implementations/SimpleDatabase.exceptions.ts","../src/infrastructure/Database/implementations/SimpleDatabase.ts","../src/infrastructure/EventBus/implementations/SimpleEventBus.ts","../src/infrastructure/EventBus/utils/createIntegrationEvent.ts","../src/infrastructure/EventBus/utils/isIntegrationEvent.ts","../src/utils/streamKey/makeStreamKey.ts","../src/infrastructure/EventStore/utils/createStoredEvent.ts","../src/infrastructure/EventStore/implementations/SimpleEventStore.exceptions.ts","../src/infrastructure/EventStore/implementations/SimpleEventStore.ts","../src/infrastructure/Outbox/implementations/GenericOutboxWorker.ts","../src/infrastructure/Outbox/implementations/InMemoryOutbox.ts","../src/infrastructure/Outbox/utils/createOutboxEntry.ts","../src/infrastructure/QueryBus/implementations/SimpleQueryBus.ts","../src/infrastructure/Repository/implementations/SimpleRepository.ts","../src/utils/isEqual/isEqual.ts","../src/infrastructure/ScenarioTest/ScenarioTest.ts","../src/utils/parseAsError/parseAsError.ts"],"names":["randomUUID","Operation","event"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Command, CommandMetadata } from '@core/Command.ts'\nimport { randomUUID } from 'node:crypto'\n\nexport function createCommand<TType extends string, TPayload>(type: TType, aggregateId: string, payload: TPayload, metadata: Partial<CommandMetadata> = {}): Command<TType, TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n aggregateId: String(aggregateId),\n payload,\n kind: 'command' as const,\n timestamp: new Date().toISOString(),\n metadata,\n })\n}\n","import type { Query, QueryMetadata } from '@core/Query.ts'\nimport { randomUUID } from 'node:crypto'\n\nexport function createQuery<TType extends string, TPayload>(type: TType, payload: TPayload, metadata: QueryMetadata = {}): Query<TType, TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n payload,\n kind: 'query',\n timestamp: new Date().toISOString(),\n metadata,\n })\n}\n","import type { Command } from '@core/Command.ts'\n\nexport function isCommand(candidate: unknown): candidate is Command<string, unknown> {\n if (candidate === null)\n return false\n if (typeof candidate !== 'object')\n return false\n if (!('type' in candidate))\n return false\n return 'kind' in candidate && candidate.kind === 'command'\n}\n","import type { Query } from '@core/Query.ts'\n\nexport function isQuery(candidate: unknown): candidate is Query<unknown> {\n if (candidate === null)\n return false\n if (typeof candidate !== 'object')\n return false\n if (!('type' in candidate))\n return false\n return 'kind' in candidate && candidate.kind === 'query'\n}\n","import type { QueryNode } from './QueryNode.ts'\n\nexport abstract class Specification<T> {\n abstract isSatisfiedBy(entity: T): boolean\n abstract toQuery(): QueryNode\n\n and(other: Specification<T>): Specification<T> {\n return new AndSpecification(this, other)\n }\n\n or(other: Specification<T>): Specification<T> {\n return new OrSpecification(this, other)\n }\n\n not(): Specification<T> {\n return new NotSpecification(this)\n }\n}\n\nexport class AndSpecification<T> extends Specification<T> {\n constructor(private left: Specification<T>, private right: Specification<T>) {\n super()\n }\n\n isSatisfiedBy(entity: T): boolean {\n return this.left.isSatisfiedBy(entity) && this.right.isSatisfiedBy(entity)\n }\n\n toQuery(): QueryNode {\n return {\n type: 'and',\n nodes: [this.left.toQuery(), this.right.toQuery()],\n }\n }\n}\n\nexport class OrSpecification<T> extends Specification<T> {\n constructor(private left: Specification<T>, private right: Specification<T>) {\n super()\n }\n\n isSatisfiedBy(entity: T): boolean {\n return this.left.isSatisfiedBy(entity) || this.right.isSatisfiedBy(entity)\n }\n\n toQuery(): QueryNode {\n return {\n type: 'or',\n nodes: [this.left.toQuery(), this.right.toQuery()],\n }\n }\n}\n\nexport class NotSpecification<T> extends Specification<T> {\n constructor(private spec: Specification<T>) {\n super()\n }\n\n isSatisfiedBy(entity: T): boolean {\n return !this.spec.isSatisfiedBy(entity)\n }\n\n toQuery(): QueryNode {\n return {\n type: 'not',\n node: this.spec.toQuery(),\n }\n }\n}\n","import type { Primitive } from '@core/types/Primitive.ts'\nimport type { QueryNode } from '../QueryNode.ts'\n\nexport function createQueryNode(type: 'eq' | 'gt' | 'lt', field: string | number | symbol, value: Primitive): QueryNode\nexport function createQueryNode(type: 'and' | 'or', field: undefined, value: QueryNode[]): QueryNode\nexport function createQueryNode(type: 'not', field: undefined, value: QueryNode): QueryNode\nexport function createQueryNode(\n type: QueryNode['type'],\n field: string | number | symbol | undefined,\n value: Primitive | QueryNode | QueryNode[],\n): QueryNode {\n switch (type) {\n case 'eq':\n case 'gt':\n case 'lt':\n return { type, field: field as string, value: value as Primitive }\n case 'and':\n case 'or':\n return { type, nodes: value as QueryNode[] }\n case 'not':\n return { type, node: value as QueryNode }\n }\n}\n","import type { Primitive } from '@core/types/Primitive.ts'\nimport type { QueryNode } from '../QueryNode.ts'\nimport { Specification } from '../Specification.ts'\nimport { createQueryNode } from '../utils/createQueryNode.ts'\n\nexport class FieldEquals<T> extends Specification<T> {\n constructor(private field: keyof T, private value: Primitive) {\n super()\n }\n\n isSatisfiedBy(entity: T): boolean {\n return entity[this.field] === this.value\n }\n\n toQuery(): QueryNode {\n return createQueryNode('eq', this.field, this.value)\n }\n}\n","export function fail(anExpression: Error) {\n return () => {\n throw anExpression\n }\n}\n","export function invariant(condition: boolean, onInvalid: () => never): asserts condition {\n if (!condition)\n onInvalid()\n}\n","import type { QueryNode } from '../QueryNode.ts'\nimport { fail } from '@utils/fail/fail.ts'\nimport { invariant } from '@utils/invariant/invariant.ts'\nimport { Specification } from '../Specification.ts'\nimport { createQueryNode } from '../utils/createQueryNode.ts'\n\nexport class FieldGreaterThan<T> extends Specification<T> {\n constructor(\n private field: keyof T,\n private value: number,\n ) {\n super()\n }\n\n private isNumber(value: unknown): value is number {\n return typeof value === 'number'\n }\n\n isSatisfiedBy(entity: T): boolean {\n const field = entity[this.field]\n invariant(\n this.isNumber(field),\n fail(new TypeError(`Field ${String(this.field)} is not a number`),\n ),\n )\n return field > this.value\n }\n\n toQuery(): QueryNode {\n return createQueryNode('gt', this.field, this.value)\n }\n}\n","import type { DomainEvent, DomainEventMetadata } from '@domain/DomainEvent.ts'\nimport { randomUUID } from 'node:crypto'\n\nexport function createDomainEvent<TPayload = unknown>(\n type: string,\n aggregateId: string,\n payload: TPayload,\n metadata: Partial<DomainEventMetadata> = {},\n): DomainEvent<TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n aggregateId,\n payload,\n source: 'internal',\n timestamp: new Date().toISOString(),\n metadata,\n })\n}\n","import type { BaseEvent } from '@domain/BaseEvent.ts'\n\nexport function isEvent(event: unknown): event is BaseEvent {\n if (typeof event !== 'object')\n return false\n if (event === null)\n return false\n if (!('type' in event))\n return false\n return 'source' in event\n}\n","import type { DomainEvent } from '../DomainEvent.ts'\nimport { isEvent } from './isEvent.ts'\n\nexport function isDomainEvent(event: unknown): event is DomainEvent {\n return isEvent(event)\n && 'aggregateId' in event\n && event.source === 'internal'\n}\n","import type { Command } from '@core/Command.ts'\nimport type { CommandHandler } from '@core/CommandHandler.ts'\nimport type { CommandBus } from '../CommandBus.ts'\n\nexport class SimpleCommandBus<TCommand extends Command> implements CommandBus<TCommand> {\n private handlers: Map<TCommand['type'], CommandHandler<TCommand>> = new Map()\n\n register(aTypeOfCommand: TCommand['type'], anHandler: CommandHandler<TCommand>): void {\n if (this.handlers.has(aTypeOfCommand)) {\n throw new Error(`Handler already registered for command type: ${aTypeOfCommand}`)\n }\n this.handlers.set(aTypeOfCommand, anHandler)\n }\n\n async execute(aCommand: TCommand): Promise<void> {\n const handler = this.handlers.get(aCommand.type)\n if (!handler) {\n throw new Error(`No handler found for command type: ${aCommand.type}`)\n }\n return handler.execute(aCommand)\n }\n}\n","import type { Specification } from '@domain/Specification/Specification.ts'\nimport type { WithIdentifier } from '../../core/types/WithIdentifier.ts'\n\nexport enum Operation {\n CREATE = 'CREATE',\n PUT = 'PUT',\n PATCH = 'PATCH',\n DELETE = 'DELETE',\n}\n\ninterface Statement<TModel> {\n operation: Operation\n payload: TModel\n}\n\nexport interface CreateStatement<TModel> extends Statement<TModel> {\n operation: Operation.CREATE\n payload: TModel\n}\n\nexport interface PutStatement<TModel> extends Statement<TModel> {\n operation: Operation.PUT\n payload: TModel\n}\n\nexport interface PatchStatement<TModel> extends Statement<Partial<TModel>> {\n operation: Operation.PATCH\n payload: WithIdentifier<Partial<TModel>>\n}\n\nexport interface DeleteStatement extends Statement<WithIdentifier> {\n operation: Operation.DELETE\n payload: WithIdentifier\n}\n\ninterface Executable<TModel, TReturnType = Promise<void>> {\n execute(tableName: string, statement: CreateStatement<TModel>): TReturnType\n execute(tableName: string, statement: PutStatement<TModel>): TReturnType\n execute(tableName: string, statement: PatchStatement<TModel>): TReturnType\n execute(tableName: string, statement: DeleteStatement): TReturnType\n}\n\ninterface QueryAble<TModel, TReturnType = Promise<TModel[]>> {\n query(collectionName: string, specification: Specification<TModel>): TReturnType\n}\n\nexport interface Database<TModel, TExecuteReturnType = Promise<void>, TQueryReturnType = Promise<TModel[]>>\n extends\n QueryAble<TModel, TQueryReturnType>,\n Executable<TModel, TExecuteReturnType> { }\n","export class RecordNotFoundException extends Error {\n constructor(id: string) {\n super(`Record not found for id: ${id}`)\n }\n}\n\nexport class DuplicateRecordException extends Error {\n constructor(id: string) {\n super(`Duplicate record found for id: ${id}`)\n }\n}\n\nexport class DatabaseOfflineException extends Error {\n constructor() {\n super(`Database is offline`)\n }\n}\n","import type { Specification } from '@domain/Specification/Specification.ts'\nimport type { WithIdentifier } from '../../../core/types/WithIdentifier.ts'\nimport type { CreateStatement, Database, DeleteStatement, PatchStatement, PutStatement } from '../Database.ts'\nimport { Operation } from '../Database.ts'\nimport { DatabaseOfflineException, DuplicateRecordException, RecordNotFoundException } from './SimpleDatabase.exceptions.ts'\n\nexport class SimpleDatabase<TModel extends WithIdentifier> implements Database<TModel, Promise<void>, Promise<TModel[]>> {\n private readonly datasource = new Map<string, TModel[]>()\n private simulateOffline = false\n\n async query(\n tableName: string,\n specification: Specification<TModel>,\n ): Promise<TModel[]> {\n if (this.simulateOffline)\n throw new DatabaseOfflineException()\n\n const tableRecords = (this.datasource.get(tableName) || [])\n return tableRecords\n .filter((record: TModel) => specification.isSatisfiedBy(record))\n }\n\n async execute(\n tableName: string,\n statement: CreateStatement<TModel> | PutStatement<TModel> | PatchStatement<TModel> | DeleteStatement,\n ): Promise<void> {\n if (this.simulateOffline)\n throw new DatabaseOfflineException()\n\n if (!this.datasource.has(tableName))\n this.datasource.set(tableName, [])\n const table = this.datasource.get(tableName)!\n\n switch (statement.operation) {\n case Operation.CREATE: {\n const isDuplicate = table.some(item => item.id === statement.payload.id)\n if (isDuplicate)\n throw new DuplicateRecordException(statement.payload.id)\n table.push(statement.payload)\n break\n }\n case Operation.PUT:{\n const index = table.findIndex(item => item.id === statement.payload.id)\n if (index === -1)\n throw new RecordNotFoundException(statement.payload.id)\n table[index] = statement.payload\n break\n }\n case Operation.PATCH:{\n const index = table.findIndex(item => item.id === statement.payload.id)\n if (index === -1)\n throw new RecordNotFoundException(statement.payload.id)\n table[index] = { ...table[index], ...statement.payload }\n break\n }\n case Operation.DELETE:{\n const index = table.findIndex(item => item.id === statement.payload.id)\n if (index === -1)\n throw new RecordNotFoundException(statement.payload.id)\n table.splice(index, 1)\n break\n }\n }\n }\n\n goOffline(): void {\n this.simulateOffline = true\n }\n}\n","import type { EventHandler } from '@core/EventHandler.ts'\nimport type { BaseEvent } from '@domain/BaseEvent.ts'\nimport type { EventConsumer, EventProducer } from '../EventBus.ts'\n\nexport class SimpleEventBus<TEvent extends BaseEvent>\nimplements EventConsumer<TEvent>, EventProducer<TEvent> {\n private handlers = new Map<string, EventHandler<TEvent>[]>()\n\n subscribe(\n stream: string,\n aHandler: EventHandler<TEvent>,\n ): void {\n const handlersForType = this.handlers.get(stream) ?? []\n handlersForType.push(aHandler)\n this.handlers.set(stream, handlersForType)\n }\n\n async consume(stream: string, anEvent: TEvent): Promise<void> {\n if (!this.handlers.has(stream))\n return\n const handlers = this.handlers.get(stream) as EventHandler<TEvent>[]\n await Promise.all(handlers.map(async (handler) => {\n return handler.handle(anEvent)\n }))\n }\n\n async publish(stream: string, anEvent: TEvent): Promise<void> {\n await this.consume(stream, anEvent)\n }\n}\n","import type { IntegrationEvent, IntegrationEventMetadata } from '../IntegrationEvent.ts'\nimport { randomUUID } from 'node:crypto'\n\nexport function createIntegrationEvent<TPayload = unknown>(type: string, payload: TPayload, metadata?: Partial<IntegrationEventMetadata>): IntegrationEvent<TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n payload,\n source: 'external',\n timestamp: new Date().toISOString(),\n metadata: {\n ...metadata,\n },\n })\n}\n","import type { IntegrationEvent } from '../IntegrationEvent.ts'\nimport { isEvent } from '@domain/utils/isEvent.ts'\n\nexport function isIntegrationEvent<TPayload>(event: unknown): event is IntegrationEvent<TPayload> {\n return isEvent(event)\n && event.source === 'external'\n}\n","import type { StreamKey } from '@utils/streamKey/StreamKey.ts'\n\nexport function makeStreamKey(streamName: string, aggregateId: string): StreamKey {\n return `${streamName}#${aggregateId}`\n}\n","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { StoredEvent } from '../StoredEvent.ts'\nimport { makeStreamKey } from '@utils/streamKey/makeStreamKey.ts'\n\nexport function createStoredEvent<TEvent extends DomainEvent>(\n streamName: string,\n version: number,\n event: TEvent,\n): StoredEvent<TEvent> {\n return Object.freeze({\n id: event.id,\n streamKey: makeStreamKey(streamName, event.aggregateId),\n version,\n createdAt: new Date().toISOString(),\n event,\n })\n}\n","export class MultipleAggregatesException extends Error {\n constructor() {\n super('EventStore append does not support multiple aggregates to be stored')\n }\n}\n","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { Database } from '@infrastructure/Database/Database.ts'\nimport type { EventStore } from '@infrastructure/EventStore/EventStore.ts'\nimport type { Outbox } from '@infrastructure/Outbox/Outbox.ts'\nimport type { StreamKey } from '@utils/streamKey/StreamKey.ts'\nimport type { StoredEvent } from '../StoredEvent.ts'\nimport { FieldEquals } from '@domain/Specification/implementations/FieldEquals.specification.ts'\nimport { Operation } from '@infrastructure/Database/Database.ts'\nimport { makeStreamKey } from '@utils/streamKey/makeStreamKey.ts'\nimport { createStoredEvent } from '../utils/createStoredEvent.ts'\nimport { MultipleAggregatesException } from './SimpleEventStore.exceptions.ts'\n\nexport class SimpleEventStore<TEvent extends DomainEvent> implements EventStore<TEvent, Promise<void>, Promise<TEvent[]>> {\n private readonly tableName: string = 'event_store'\n\n constructor(\n private readonly database: Database<StoredEvent<TEvent>, Promise<void>, Promise<StoredEvent<TEvent>[]>>,\n private readonly outbox?: Outbox,\n ) { }\n\n async load(streamName: string, aggregateId: string): Promise<TEvent[]> {\n const streamKey: StreamKey = makeStreamKey(streamName, aggregateId)\n const specification = new FieldEquals('streamKey', streamKey)\n const storedEvents = await this.database.query(this.tableName, specification)\n return storedEvents.map(storedEvent => storedEvent.event)\n }\n\n async append(streamName: string, events: TEvent[]): Promise<void> {\n const uniqueAggregateIds = new Set(events.map(event => event.aggregateId))\n if (uniqueAggregateIds.size > 1)\n throw new MultipleAggregatesException()\n\n const event = events[0]\n const currentStream = await this.load(streamName, event.aggregateId)\n const eventsToStore = events\n .map(event => createStoredEvent(streamName, currentStream.length + 1, event))\n await Promise.all(\n eventsToStore.map(async payload => this.database.execute(this.tableName, { operation: Operation.CREATE, payload }),\n ),\n )\n await Promise.all(events.map(async event => this.outbox?.enqueue(event)))\n }\n}\n","import type { BaseEvent } from '@domain/BaseEvent.ts'\nimport type { EventProducer } from '@infrastructure/EventBus/EventBus.js'\nimport type { OutboxWorker } from '@infrastructure/Outbox/OutboxWorker.ts'\nimport type { Outbox } from '../Outbox.ts'\n\nexport class GenericOutboxWorker implements OutboxWorker {\n constructor(\n protected outbox: Outbox,\n protected eventBus: EventProducer<BaseEvent>,\n protected stream: string,\n ) {}\n\n async runOnce(): Promise<void> {\n const pending = await this.outbox.getPending()\n\n await Promise.all(pending.map(async (entry) => {\n try {\n await this.eventBus.publish(this.stream, entry.event)\n await this.outbox.markAsPublished(entry.id)\n }\n catch {\n await this.outbox.markAsFailed(entry.id)\n }\n }))\n }\n\n async tick(): Promise<void> {\n await this.runOnce()\n }\n\n start(intervalMs: number): void {\n setInterval(() => {\n void this.tick().catch(console.error)\n }, intervalMs)\n }\n}\n","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { Outbox } from '../Outbox.ts'\nimport type { OutboxEntry } from '../OutboxEntry.ts'\n\nexport class InMemoryOutbox implements Outbox {\n protected entries: OutboxEntry[] = []\n protected idCounter = 0\n\n async enqueue(event: DomainEvent<unknown>): Promise<void> {\n this.entries.push({\n id: (this.idCounter++).toString(),\n event,\n published: false,\n retryCount: 0,\n })\n }\n\n async getPending(limit = 100): Promise<OutboxEntry[]> {\n return this.entries.filter(e => !e.published).slice(0, limit)\n }\n\n async markAsPublished(id: string): Promise<void> {\n const entry = this.entries.find(e => e.id === id)\n if (entry) {\n entry.published = true\n }\n }\n\n async markAsFailed(id: string): Promise<void> {\n const entry = this.entries.find(e => e.id === id)\n if (entry) {\n entry.retryCount += 1\n entry.lastAttemptAt = new Date().toISOString()\n }\n }\n}\n","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { OutboxEntry } from '../OutboxEntry.ts'\nimport { randomUUID } from 'node:crypto'\n\nexport function createOutboxEntry(\n event: DomainEvent<unknown>,\n): OutboxEntry {\n return Object.freeze({\n id: randomUUID(),\n event,\n published: false,\n retryCount: 0,\n lastAttemptAt: undefined,\n })\n}\n","import type { Query } from '@core/Query.ts'\nimport type { QueryHandler } from '@core/QueryHandler.ts'\nimport type { QueryBus } from '../QueryBus.ts'\n\nexport class SimpleQueryBus<TQuery extends Query, TProjection> implements QueryBus<TQuery, Promise<TProjection>> {\n private handlers: Map<TQuery['type'], QueryHandler<TQuery, Promise<TProjection>>> = new Map()\n\n register(\n aTypeOfQuery: TQuery['type'],\n anHandler: QueryHandler<TQuery, Promise<TProjection>>,\n ): void {\n if (this.handlers.has(aTypeOfQuery)) {\n throw new Error(`Handler already registered for query type: ${aTypeOfQuery}`)\n }\n this.handlers.set(aTypeOfQuery, anHandler)\n }\n\n async execute(aQuery: TQuery): Promise<TProjection> {\n const handler = this.handlers.get(aQuery.type)\n if (!handler) {\n throw new Error(`No handler found for query type: ${aQuery.type}`)\n }\n return handler.execute(aQuery)\n }\n}\n","import type { Decider } from '@domain/Decider.ts'\nimport type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { Repository } from '@domain/Repository.ts'\nimport type { EventStore } from '@infrastructure/EventStore/EventStore.ts'\n\nexport class SimpleRepository<TState, TCommand, TEvent extends DomainEvent> implements Repository<TEvent, Promise<TState>, Promise<void>> {\n constructor(\n private readonly eventStore: EventStore<TEvent, Promise<void>, Promise<TEvent[]>>,\n readonly streamName: string,\n private readonly evolveFn: Decider<TState, TCommand, TEvent>['evolve'],\n private readonly initialState: Decider<TState, TCommand, TEvent>['initialState'],\n ) {\n }\n\n async load(aggregateId: string): Promise<TState> {\n const pastEvents = await this.eventStore.load(this.streamName, aggregateId)\n return pastEvents\n .reduce<TState>(this.evolveFn, this.initialState(aggregateId))\n }\n\n async store(events: TEvent[]): Promise<void> {\n await Promise.all(\n events.map(\n async event => this.eventStore.append(\n this.streamName,\n [event],\n ),\n ),\n )\n }\n}\n","export function isEqual<T>(a: T, b: T): boolean {\n if (a === b) {\n return true\n }\n\n // eslint-disable-next-line ts/strict-boolean-expressions\n const bothAreObjects = a && b && typeof a === 'object' && typeof b === 'object'\n\n return Boolean(\n bothAreObjects\n && Object.keys(a).length === Object.keys(b).length\n && Object.entries(a).every(([k, v]) => isEqual(v, b[k as keyof T])),\n )\n}\n","import type { Command } from '@core/Command.ts'\nimport type { Query } from '@core/Query.ts'\nimport type { BaseEvent } from '@domain/BaseEvent.ts'\nimport type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { Repository } from '@domain/Repository.ts'\nimport type { EventConsumer, EventProducer } from '@infrastructure/EventBus/EventBus.js'\nimport type { EventStore } from '@infrastructure/EventStore/EventStore.ts'\nimport type { OutboxWorker } from '@infrastructure/Outbox/OutboxWorker.ts'\nimport type { CommandBus } from '../CommandBus/CommandBus.ts'\nimport type { IntegrationEvent } from '../EventBus/IntegrationEvent.ts'\nimport type { QueryBus } from '../QueryBus/QueryBus.ts'\nimport { isCommand } from '@core/utils/isCommand.ts'\nimport { isQuery } from '@core/utils/isQuery.ts'\nimport { isDomainEvent } from '@domain/utils/isDomainEvent.ts'\nimport { isEvent } from '@domain/utils/isEvent.ts'\nimport { fail } from '@utils/fail/fail.ts'\nimport { invariant } from '@utils/invariant/invariant.ts'\nimport { isEqual } from '@utils/isEqual/isEqual.ts'\nimport { isIntegrationEvent } from '../EventBus/utils/isIntegrationEvent.ts'\n\ntype GivenInput = (DomainEvent | IntegrationEvent)[]\ntype WhenInput = Command | Query | DomainEvent | IntegrationEvent\ntype ThenInput = DomainEvent | Array<Record<string, unknown>>\n\nexport class ScenarioTest<TState, TEvent extends DomainEvent> {\n private givenInput: GivenInput = []\n private whenInput: WhenInput | undefined\n\n constructor(\n private readonly streamName: string,\n private readonly eventBus: EventProducer<BaseEvent> & EventConsumer<BaseEvent>,\n private readonly eventStore: EventStore<TEvent, Promise<void>, Promise<TEvent[]>>,\n private readonly commandBus: CommandBus<Command>,\n private readonly queryBus: QueryBus<Query, Promise<Record<string, unknown>[]>>,\n private readonly repository: Repository<DomainEvent, Promise<TState>>,\n private readonly outboxWorker: OutboxWorker,\n ) {}\n\n given(...events: GivenInput): {\n when(action: WhenInput): ReturnType<ScenarioTest<TState, TEvent>['when']>\n then(outcome: ThenInput): Promise<void>\n } {\n this.givenInput = events\n return {\n when: this.when.bind(this),\n then: this.then.bind(this),\n }\n }\n\n when(action: WhenInput): {\n then(outcome: ThenInput): Promise<void>\n } {\n this.whenInput = action\n return {\n then: this.then.bind(this),\n }\n }\n\n async then(thenInput: ThenInput): Promise<void> {\n const domainEvents = this.givenInput\n .filter(isDomainEvent)\n const integrationEvents = this.givenInput\n .filter(isIntegrationEvent)\n\n await Promise.all([\n this.repository.store(domainEvents),\n ...integrationEvents.map(async event => this.eventBus.consume(this.streamName, event)),\n ])\n\n if (!this.whenInput) {\n throw new Error('In the ScenarioTest, the when-step cannot be empty')\n }\n\n if (isCommand(this.whenInput)) {\n invariant(isDomainEvent(thenInput), fail(new TypeError('When \\\"command\\\" expects a domain event in the then-step')))\n await this.handleCommand(this.whenInput, thenInput)\n }\n\n if (isQuery(this.whenInput)) {\n invariant(Array.isArray(thenInput), fail(new TypeError('When \\\"query\\\" expects an array of expected results in the then-step')))\n await this.handleQuery(this.whenInput, thenInput)\n }\n\n if (isDomainEvent(this.whenInput) || isIntegrationEvent(this.whenInput)) {\n invariant(isDomainEvent(thenInput), fail(new TypeError('When \\\"domain event\\\" or \\\"integration event\\\" expects a domain event in the then-step')))\n await this.handleEvent(this.whenInput, thenInput)\n }\n }\n\n private async handleCommand(command: Command, outcome: DomainEvent): Promise<void> {\n await this.commandBus.execute(command)\n const actualEvents = await this.eventStore.load(this.streamName, outcome.aggregateId)\n const foundEvent = actualEvents.findLast(\n event =>\n isDomainEvent(event)\n && event.aggregateId === outcome.aggregateId\n && event.type === outcome.type,\n )\n invariant(!!foundEvent, fail(new Error('ScenarioTest: event/command was not found')))\n invariant(\n outcome.type === foundEvent.type,\n fail(new Error('ScenarioTest: event/command type was not equal')),\n )\n invariant(\n outcome.aggregateId === foundEvent.aggregateId,\n fail(new Error('ScenarioTest: event/command aggregate id was not equal')),\n )\n invariant(\n isEqual(outcome.payload, foundEvent.payload),\n fail(new Error('ScenarioTest: event/command payload was not equal')),\n )\n }\n\n private async handleQuery(query: Query, expected: Array<Record<string, unknown>>): Promise<void> {\n await this.outboxWorker.tick()\n const actual = await this.queryBus.execute(query)\n invariant(\n isEqual(actual, expected),\n fail(new Error('ScenarioTest: a different query result was returned')),\n )\n }\n\n private async handleEvent(\n event: DomainEvent | IntegrationEvent,\n outcome: DomainEvent,\n ): Promise<void> {\n await this.eventBus.publish(this.streamName, event)\n const actualEvents = await this.eventStore.load(this.streamName, outcome.aggregateId)\n const foundEvent = actualEvents.findLast(\n event =>\n isEvent(event) && event.aggregateId === outcome.aggregateId && event.type === outcome.type,\n )\n invariant(!!foundEvent, fail(new Error('ScenarioTest: event was not found')))\n invariant(isEvent(foundEvent), fail(new Error('ScenarioTest: event is not of type event')))\n invariant(\n outcome.type === foundEvent.type,\n fail(new Error('ScenarioTest: event type was not equal')),\n )\n invariant(\n outcome.aggregateId === foundEvent.aggregateId,\n fail(new Error('ScenarioTest: event aggregate id was not equal')),\n )\n invariant(\n isEqual(outcome.payload, foundEvent.payload),\n fail(new Error('ScenarioTest: event payload was not equal')),\n )\n }\n}\n","export function parseAsError(value: unknown): Error {\n if (value instanceof Error)\n return value\n if (typeof value === 'string')\n return new Error(value)\n try {\n const json = JSON.stringify(value)\n return new Error(json ?? String(value))\n }\n catch {\n return new Error('Unknown error')\n }\n}\n"]}
|
|
@@ -45,7 +45,7 @@ interface DomainEvent<TPayload = unknown> {
|
|
|
45
45
|
aggregateId: string;
|
|
46
46
|
source: 'internal';
|
|
47
47
|
payload: TPayload;
|
|
48
|
-
timestamp:
|
|
48
|
+
timestamp: string;
|
|
49
49
|
metadata: Partial<DomainEventMetadata>;
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -140,38 +140,35 @@ type QueryNode = {
|
|
|
140
140
|
node: QueryNode;
|
|
141
141
|
};
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
isSatisfiedBy(entity: T): boolean;
|
|
145
|
-
}
|
|
146
|
-
declare abstract class CompositeSpecification<T> implements Specification<T> {
|
|
143
|
+
declare abstract class Specification<T> {
|
|
147
144
|
abstract isSatisfiedBy(entity: T): boolean;
|
|
148
145
|
abstract toQuery(): QueryNode;
|
|
149
|
-
and(other:
|
|
150
|
-
or(other:
|
|
151
|
-
not():
|
|
146
|
+
and(other: Specification<T>): Specification<T>;
|
|
147
|
+
or(other: Specification<T>): Specification<T>;
|
|
148
|
+
not(): Specification<T>;
|
|
152
149
|
}
|
|
153
|
-
declare class AndSpecification<T> extends
|
|
150
|
+
declare class AndSpecification<T> extends Specification<T> {
|
|
154
151
|
private left;
|
|
155
152
|
private right;
|
|
156
|
-
constructor(left:
|
|
153
|
+
constructor(left: Specification<T>, right: Specification<T>);
|
|
157
154
|
isSatisfiedBy(entity: T): boolean;
|
|
158
155
|
toQuery(): QueryNode;
|
|
159
156
|
}
|
|
160
|
-
declare class OrSpecification<T> extends
|
|
157
|
+
declare class OrSpecification<T> extends Specification<T> {
|
|
161
158
|
private left;
|
|
162
159
|
private right;
|
|
163
|
-
constructor(left:
|
|
160
|
+
constructor(left: Specification<T>, right: Specification<T>);
|
|
164
161
|
isSatisfiedBy(entity: T): boolean;
|
|
165
162
|
toQuery(): QueryNode;
|
|
166
163
|
}
|
|
167
|
-
declare class NotSpecification<T> extends
|
|
164
|
+
declare class NotSpecification<T> extends Specification<T> {
|
|
168
165
|
private spec;
|
|
169
|
-
constructor(spec:
|
|
166
|
+
constructor(spec: Specification<T>);
|
|
170
167
|
isSatisfiedBy(entity: T): boolean;
|
|
171
168
|
toQuery(): QueryNode;
|
|
172
169
|
}
|
|
173
170
|
|
|
174
|
-
declare class FieldEquals<T> extends
|
|
171
|
+
declare class FieldEquals<T> extends Specification<T> {
|
|
175
172
|
private field;
|
|
176
173
|
private value;
|
|
177
174
|
constructor(field: keyof T, value: Primitive);
|
|
@@ -179,7 +176,7 @@ declare class FieldEquals<T> extends CompositeSpecification<T> {
|
|
|
179
176
|
toQuery(): QueryNode;
|
|
180
177
|
}
|
|
181
178
|
|
|
182
|
-
declare class FieldGreaterThan<T> extends
|
|
179
|
+
declare class FieldGreaterThan<T> extends Specification<T> {
|
|
183
180
|
private field;
|
|
184
181
|
private value;
|
|
185
182
|
constructor(field: keyof T, value: number);
|
|
@@ -201,10 +198,10 @@ declare function isEvent(event: unknown): event is BaseEvent;
|
|
|
201
198
|
interface Registerable$1<TCommand extends Command, TResult = void> {
|
|
202
199
|
register(aTypeOfCommand: TCommand['type'], anHandler: CommandHandler<TCommand>): TResult;
|
|
203
200
|
}
|
|
204
|
-
interface Executable$
|
|
201
|
+
interface Executable$2<TCommand extends Command, TResult = Promise<void>> {
|
|
205
202
|
execute(aCommand: TCommand): TResult;
|
|
206
203
|
}
|
|
207
|
-
interface CommandBus<TCommand extends Command, TExecutionResult = Promise<void>, TRegisterResult = void> extends Executable$
|
|
204
|
+
interface CommandBus<TCommand extends Command, TExecutionResult = Promise<void>, TRegisterResult = void> extends Executable$2<TCommand, TExecutionResult>, Registerable$1<TCommand, TRegisterResult> {
|
|
208
205
|
}
|
|
209
206
|
|
|
210
207
|
declare class SimpleCommandBus<TCommand extends Command> implements CommandBus<TCommand> {
|
|
@@ -239,32 +236,26 @@ interface DeleteStatement extends Statement<WithIdentifier> {
|
|
|
239
236
|
operation: Operation.DELETE;
|
|
240
237
|
payload: WithIdentifier;
|
|
241
238
|
}
|
|
242
|
-
interface Executable$
|
|
239
|
+
interface Executable$1<TModel, TReturnType = Promise<void>> {
|
|
243
240
|
execute(tableName: string, statement: CreateStatement<TModel>): TReturnType;
|
|
244
241
|
execute(tableName: string, statement: PutStatement<TModel>): TReturnType;
|
|
245
242
|
execute(tableName: string, statement: PatchStatement<TModel>): TReturnType;
|
|
246
243
|
execute(tableName: string, statement: DeleteStatement): TReturnType;
|
|
247
244
|
}
|
|
248
245
|
interface QueryAble<TModel, TReturnType = Promise<TModel[]>> {
|
|
249
|
-
query(collectionName: string, specification:
|
|
246
|
+
query(collectionName: string, specification: Specification<TModel>): TReturnType;
|
|
250
247
|
}
|
|
251
|
-
interface Database<TModel, TExecuteReturnType = Promise<void>, TQueryReturnType = Promise<TModel[]>> extends QueryAble<TModel, TQueryReturnType>, Executable$
|
|
248
|
+
interface Database<TModel, TExecuteReturnType = Promise<void>, TQueryReturnType = Promise<TModel[]>> extends QueryAble<TModel, TQueryReturnType>, Executable$1<TModel, TExecuteReturnType> {
|
|
252
249
|
}
|
|
253
250
|
|
|
254
251
|
declare class SimpleDatabase<TModel extends WithIdentifier> implements Database<TModel, Promise<void>, Promise<TModel[]>> {
|
|
255
252
|
private readonly datasource;
|
|
256
253
|
private simulateOffline;
|
|
257
|
-
query(tableName: string, specification:
|
|
254
|
+
query(tableName: string, specification: Specification<TModel>): Promise<TModel[]>;
|
|
258
255
|
execute(tableName: string, statement: CreateStatement<TModel> | PutStatement<TModel> | PatchStatement<TModel> | DeleteStatement): Promise<void>;
|
|
259
256
|
goOffline(): void;
|
|
260
257
|
}
|
|
261
258
|
|
|
262
|
-
interface Executable$1<TInput, TResult> {
|
|
263
|
-
execute(input: TInput): TResult;
|
|
264
|
-
}
|
|
265
|
-
interface Directive<TInput, TResult = void> extends Executable$1<TInput, TResult> {
|
|
266
|
-
}
|
|
267
|
-
|
|
268
259
|
interface EventProducer<TEvent extends BaseEvent, TReturnType = Promise<void>> {
|
|
269
260
|
publish(stream: string, anEvent: TEvent): TReturnType;
|
|
270
261
|
}
|
|
@@ -284,23 +275,13 @@ declare function createIntegrationEvent<TPayload = unknown>(type: string, payloa
|
|
|
284
275
|
|
|
285
276
|
declare function isIntegrationEvent<TPayload>(event: unknown): event is IntegrationEvent<TPayload>;
|
|
286
277
|
|
|
287
|
-
declare function fail(anExpression: Error): () => never;
|
|
288
|
-
|
|
289
|
-
declare function invariant(condition: boolean, onInvalid: () => never): asserts condition;
|
|
290
|
-
|
|
291
|
-
declare function isEqual<T>(a: T, b: T): boolean;
|
|
292
|
-
|
|
293
|
-
declare function parseAsError(value: unknown): Error;
|
|
294
|
-
|
|
295
278
|
type StreamKey = `${string}#${string}`;
|
|
296
279
|
|
|
297
|
-
declare function makeStreamKey(streamName: string, aggregateId: string): StreamKey;
|
|
298
|
-
|
|
299
280
|
interface StoredEvent<TEvent> {
|
|
300
281
|
id: string;
|
|
301
282
|
streamKey: StreamKey;
|
|
302
283
|
version: number;
|
|
303
|
-
|
|
284
|
+
createdAt: string;
|
|
304
285
|
event: TEvent;
|
|
305
286
|
}
|
|
306
287
|
|
|
@@ -426,4 +407,14 @@ declare class ScenarioTest<TState, TEvent extends DomainEvent> {
|
|
|
426
407
|
private handleEvent;
|
|
427
408
|
}
|
|
428
409
|
|
|
429
|
-
|
|
410
|
+
declare function fail(anExpression: Error): () => never;
|
|
411
|
+
|
|
412
|
+
declare function invariant(condition: boolean, onInvalid: () => never): asserts condition;
|
|
413
|
+
|
|
414
|
+
declare function isEqual<T>(a: T, b: T): boolean;
|
|
415
|
+
|
|
416
|
+
declare function parseAsError(value: unknown): Error;
|
|
417
|
+
|
|
418
|
+
declare function makeStreamKey(streamName: string, aggregateId: string): StreamKey;
|
|
419
|
+
|
|
420
|
+
export { type AggregateRoot, AndSpecification, type BaseEvent, type Command, type CommandBus, type CommandHandler, type CommandMetadata, type CreateStatement, type Database, type Decider, type DeleteStatement, type DomainEvent, type DomainEventMetadata, type EventBasedAggregateRoot, type EventConsumer, type EventHandler, type EventProducer, type EventStore, FieldEquals, FieldGreaterThan, type FilledArray, GenericOutboxWorker, InMemoryOutbox, type IntegrationEvent, type IntegrationEventMetadata, type Maybe, type Module, NotSpecification, type Nullable, Operation, OrSpecification, type Outbox, type OutboxEntry, type OutboxWorker, type PatchStatement, type Primitive, type PutStatement, type Query, type QueryBus, type QueryHandler, type QueryMetadata, type QueryNode, type Repository, ScenarioTest, SimpleCommandBus, SimpleDatabase, SimpleEventBus, SimpleEventStore, SimpleQueryBus, SimpleRepository, Specification, type StoredEvent, type StreamKey, type WithIdentifier, createCommand, createDomainEvent, createIntegrationEvent, createOutboxEntry, createQuery, createQueryNode, createStoredEvent, fail, invariant, isCommand, isDomainEvent, isEqual, isEvent, isIntegrationEvent, isQuery, makeStreamKey, parseAsError };
|