@hexaijs/core 0.4.0 → 0.5.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/dist/{message.d.ts → event-store-BDib72ud.d.ts} +19 -7
- package/dist/index.d.ts +67 -5
- package/dist/index.js +202 -19
- package/dist/index.js.map +1 -1
- package/dist/test/index.d.ts +38 -7
- package/dist/test/index.js +304 -42
- package/dist/test/index.js.map +1 -1
- package/package.json +6 -7
- package/dist/config.d.ts +0 -2
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -5
- package/dist/config.js.map +0 -1
- package/dist/domain/aggregate-root.d.ts +0 -11
- package/dist/domain/aggregate-root.d.ts.map +0 -1
- package/dist/domain/aggregate-root.js +0 -21
- package/dist/domain/aggregate-root.js.map +0 -1
- package/dist/domain/domain-error.d.ts +0 -11
- package/dist/domain/domain-error.d.ts.map +0 -1
- package/dist/domain/domain-error.js +0 -25
- package/dist/domain/domain-error.js.map +0 -1
- package/dist/domain/domain-event.d.ts +0 -5
- package/dist/domain/domain-event.d.ts.map +0 -1
- package/dist/domain/domain-event.js +0 -11
- package/dist/domain/domain-event.js.map +0 -1
- package/dist/domain/identifiable.d.ts +0 -11
- package/dist/domain/identifiable.d.ts.map +0 -1
- package/dist/domain/identifiable.js +0 -18
- package/dist/domain/identifiable.js.map +0 -1
- package/dist/domain/index.d.ts +0 -6
- package/dist/domain/index.d.ts.map +0 -1
- package/dist/domain/index.js +0 -22
- package/dist/domain/index.js.map +0 -1
- package/dist/domain/repository.d.ts +0 -16
- package/dist/domain/repository.d.ts.map +0 -1
- package/dist/domain/repository.js +0 -25
- package/dist/domain/repository.js.map +0 -1
- package/dist/event-store.d.ts +0 -13
- package/dist/event-store.d.ts.map +0 -1
- package/dist/event-store.js +0 -3
- package/dist/event-store.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/message.d.ts.map +0 -1
- package/dist/message.js +0 -120
- package/dist/message.js.map +0 -1
- package/dist/test/dummy-message.d.ts +0 -8
- package/dist/test/dummy-message.d.ts.map +0 -1
- package/dist/test/dummy-message.js +0 -22
- package/dist/test/dummy-message.js.map +0 -1
- package/dist/test/expect.d.ts +0 -3
- package/dist/test/expect.d.ts.map +0 -1
- package/dist/test/expect.js +0 -13
- package/dist/test/expect.js.map +0 -1
- package/dist/test/in-memory-event-store.d.ts +0 -11
- package/dist/test/in-memory-event-store.d.ts.map +0 -1
- package/dist/test/in-memory-event-store.js +0 -38
- package/dist/test/in-memory-event-store.js.map +0 -1
- package/dist/test/index.d.ts.map +0 -1
- package/dist/test/matchers.d.ts +0 -5
- package/dist/test/matchers.d.ts.map +0 -1
- package/dist/test/matchers.js +0 -77
- package/dist/test/matchers.js.map +0 -1
- package/dist/test/partial-match.d.ts +0 -4
- package/dist/test/partial-match.d.ts.map +0 -1
- package/dist/test/partial-match.js +0 -33
- package/dist/test/partial-match.js.map +0 -1
- package/dist/test/utils.d.ts +0 -5
- package/dist/test/utils.d.ts.map +0 -1
- package/dist/test/utils.js +0 -25
- package/dist/test/utils.js.map +0 -1
- package/dist/unit-of-work.d.ts +0 -13
- package/dist/unit-of-work.d.ts.map +0 -1
- package/dist/unit-of-work.js +0 -10
- package/dist/unit-of-work.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
type Version = string | number | undefined;
|
|
2
|
-
|
|
2
|
+
interface MessageHeaders {
|
|
3
3
|
id: string;
|
|
4
4
|
type: string;
|
|
5
5
|
intent?: string;
|
|
@@ -11,7 +11,7 @@ type ExtraHeaderField = Exclude<keyof MessageHeaders, "id" | "type" | "intent" |
|
|
|
11
11
|
type RawMessageHeaders = Omit<MessageHeaders, "createdAt"> & {
|
|
12
12
|
createdAt: string | Date;
|
|
13
13
|
};
|
|
14
|
-
|
|
14
|
+
declare class Message<Payload = any> {
|
|
15
15
|
protected readonly payload: Payload;
|
|
16
16
|
protected headers: MessageHeaders;
|
|
17
17
|
static getSchemaVersion(): Version;
|
|
@@ -41,14 +41,26 @@ export declare class Message<Payload = any> {
|
|
|
41
41
|
protected serializePayload(payload: Payload): unknown;
|
|
42
42
|
asType<M extends MessageClass>(cls: M): InstanceType<M>;
|
|
43
43
|
}
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
type AnyMessage = Message;
|
|
45
|
+
type MessageClass<T extends Message = Message> = {
|
|
46
46
|
getSchemaVersion(): Version;
|
|
47
47
|
getType(): string;
|
|
48
48
|
getIntent(): string | undefined;
|
|
49
49
|
from: (rawPayload: any, header?: MessageHeaders) => T;
|
|
50
50
|
new (...args: any[]): T;
|
|
51
51
|
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
type PayloadOf<M> = M extends Message<infer P> ? P : never;
|
|
53
|
+
|
|
54
|
+
interface StoredEvent {
|
|
55
|
+
position: number;
|
|
56
|
+
event: Message;
|
|
57
|
+
}
|
|
58
|
+
interface EventStoreFetchResult {
|
|
59
|
+
events: StoredEvent[];
|
|
60
|
+
lastPosition: number;
|
|
61
|
+
}
|
|
62
|
+
interface EventStore {
|
|
63
|
+
fetch(afterPosition: number, limit?: number): Promise<EventStoreFetchResult>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { type AnyMessage as A, type EventStore as E, Message as M, type PayloadOf as P, type StoredEvent as S, type EventStoreFetchResult as a, type MessageClass as b, type MessageHeaders as c };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,67 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { M as Message } from './event-store-BDib72ud.js';
|
|
2
|
+
export { A as AnyMessage, E as EventStore, a as EventStoreFetchResult, b as MessageClass, c as MessageHeaders, P as PayloadOf, S as StoredEvent } from './event-store-BDib72ud.js';
|
|
3
|
+
|
|
4
|
+
declare class DomainEvent<P extends Record<string, any> = Record<string, unknown>> extends Message<P> {
|
|
5
|
+
static getIntent(): string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
declare class Id<T extends string | number> {
|
|
9
|
+
private readonly value;
|
|
10
|
+
constructor(value: T);
|
|
11
|
+
getValue(): T;
|
|
12
|
+
equals(other: Id<T>): boolean;
|
|
13
|
+
}
|
|
14
|
+
type IdOf<T> = T extends Identifiable<infer Id> ? Id : never;
|
|
15
|
+
interface Identifiable<T extends Id<string | number> = Id<string>> {
|
|
16
|
+
getId(): T;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare class AggregateRoot<T extends Id<string | number>> implements Identifiable<T> {
|
|
20
|
+
protected readonly id: T;
|
|
21
|
+
protected events: DomainEvent[];
|
|
22
|
+
constructor(id: T);
|
|
23
|
+
getId(): T;
|
|
24
|
+
protected raise(event: DomainEvent): void;
|
|
25
|
+
getEventsOccurred(): DomainEvent[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
declare class DomainError extends Error {
|
|
29
|
+
}
|
|
30
|
+
declare class InvariantNotSatisfiedError extends DomainError {
|
|
31
|
+
readonly code: string;
|
|
32
|
+
constructor(code: string, message?: string);
|
|
33
|
+
}
|
|
34
|
+
declare class ValidationError extends InvariantNotSatisfiedError {
|
|
35
|
+
readonly field: string;
|
|
36
|
+
constructor(field: string, code: string, message?: string);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface Repository<T extends Identifiable<any>> {
|
|
40
|
+
get(id: IdOf<T>): Promise<T>;
|
|
41
|
+
add(entity: T): Promise<void>;
|
|
42
|
+
update(entity: T): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
declare class RepositoryError extends Error {
|
|
45
|
+
constructor(message: string);
|
|
46
|
+
}
|
|
47
|
+
declare class DuplicateObjectError extends RepositoryError {
|
|
48
|
+
constructor(message: string);
|
|
49
|
+
}
|
|
50
|
+
declare class ObjectNotFoundError extends RepositoryError {
|
|
51
|
+
constructor(message: string);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
declare enum Propagation {
|
|
55
|
+
NEW = "new",
|
|
56
|
+
EXISTING = "existing",
|
|
57
|
+
NESTED = "nested"
|
|
58
|
+
}
|
|
59
|
+
interface BaseUnitOfWorkOptions {
|
|
60
|
+
propagation: Propagation;
|
|
61
|
+
}
|
|
62
|
+
interface UnitOfWork<Client = unknown, Options extends BaseUnitOfWorkOptions = BaseUnitOfWorkOptions> {
|
|
63
|
+
getClient(): Client;
|
|
64
|
+
wrap<T>(fn: (client: Client) => Promise<T>, options?: Partial<Options>): Promise<T>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export { AggregateRoot, type BaseUnitOfWorkOptions, DomainError, DomainEvent, DuplicateObjectError, Id, type IdOf, type Identifiable, InvariantNotSatisfiedError, Message, ObjectNotFoundError, Propagation, type Repository, RepositoryError, type UnitOfWork, ValidationError };
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,204 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { v4 } from 'uuid';
|
|
2
|
+
|
|
3
|
+
// src/domain/aggregate-root.ts
|
|
4
|
+
var AggregateRoot = class {
|
|
5
|
+
constructor(id) {
|
|
6
|
+
this.id = id;
|
|
7
|
+
}
|
|
8
|
+
events = [];
|
|
9
|
+
getId() {
|
|
10
|
+
return this.id;
|
|
11
|
+
}
|
|
12
|
+
raise(event) {
|
|
13
|
+
this.events.push(event);
|
|
14
|
+
}
|
|
15
|
+
getEventsOccurred() {
|
|
16
|
+
return [...this.events];
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// src/domain/domain-error.ts
|
|
21
|
+
var DomainError = class extends Error {
|
|
22
|
+
};
|
|
23
|
+
var InvariantNotSatisfiedError = class extends DomainError {
|
|
24
|
+
constructor(code, message = "") {
|
|
25
|
+
super(message);
|
|
26
|
+
this.code = code;
|
|
27
|
+
this.name = "InvariantNotSatisfiedError";
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
var ValidationError = class extends InvariantNotSatisfiedError {
|
|
31
|
+
constructor(field, code, message = "") {
|
|
32
|
+
super(code, message);
|
|
33
|
+
this.field = field;
|
|
34
|
+
this.name = "ValidationError";
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
var Message = class {
|
|
38
|
+
constructor(payload, headers = {}) {
|
|
39
|
+
this.payload = payload;
|
|
40
|
+
this.headers = Object.freeze(
|
|
41
|
+
this.constructor.mergeHeaders(headers)
|
|
42
|
+
);
|
|
43
|
+
if (payload && typeof payload === "object") {
|
|
44
|
+
Object.freeze(payload);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
headers;
|
|
48
|
+
static getSchemaVersion() {
|
|
49
|
+
return this.schemaVersion ?? void 0;
|
|
50
|
+
}
|
|
51
|
+
static getType() {
|
|
52
|
+
return this.type ?? this.name;
|
|
53
|
+
}
|
|
54
|
+
static getIntent() {
|
|
55
|
+
return this.intent ?? void 0;
|
|
56
|
+
}
|
|
57
|
+
static newHeaders(...excludes) {
|
|
58
|
+
return generateHeaderFor(this, ...excludes);
|
|
59
|
+
}
|
|
60
|
+
static from(rawPayload, headers) {
|
|
61
|
+
const payload = this.deserializeRawPayload(rawPayload);
|
|
62
|
+
return new this(
|
|
63
|
+
payload,
|
|
64
|
+
headers ? this.deserializeRawHeaders(headers) : this.newHeaders()
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
static deserializeRawPayload(rawPayload) {
|
|
68
|
+
return rawPayload;
|
|
69
|
+
}
|
|
70
|
+
static deserializeRawHeaders(headers) {
|
|
71
|
+
headers.createdAt = new Date(headers.createdAt);
|
|
72
|
+
return headers;
|
|
73
|
+
}
|
|
74
|
+
static mergeHeaders(headers) {
|
|
75
|
+
return {
|
|
76
|
+
...this.newHeaders(...Object.keys(headers)),
|
|
77
|
+
...headers
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
withHeader(field, value) {
|
|
81
|
+
const newHeaders = { ...this.headers, [field]: value };
|
|
82
|
+
return new this.constructor(this.payload, newHeaders);
|
|
83
|
+
}
|
|
84
|
+
clone() {
|
|
85
|
+
return new this.constructor(this.payload, { ...this.headers });
|
|
86
|
+
}
|
|
87
|
+
getHeader(field) {
|
|
88
|
+
return this.headers[field];
|
|
89
|
+
}
|
|
90
|
+
getHeaders() {
|
|
91
|
+
return Object.freeze({ ...this.headers });
|
|
92
|
+
}
|
|
93
|
+
getPayload() {
|
|
94
|
+
return this.payload;
|
|
95
|
+
}
|
|
96
|
+
getMessageId() {
|
|
97
|
+
return this.headers.id;
|
|
98
|
+
}
|
|
99
|
+
getMessageType() {
|
|
100
|
+
return this.headers.type;
|
|
101
|
+
}
|
|
102
|
+
getSchemaVersion() {
|
|
103
|
+
return this.headers.schemaVersion;
|
|
104
|
+
}
|
|
105
|
+
getTimestamp() {
|
|
106
|
+
return this.headers.createdAt;
|
|
107
|
+
}
|
|
108
|
+
getIntent() {
|
|
109
|
+
return this.constructor.getIntent();
|
|
110
|
+
}
|
|
111
|
+
serialize() {
|
|
112
|
+
return JSON.parse(JSON.stringify(this.doSerialize()));
|
|
113
|
+
}
|
|
114
|
+
doSerialize() {
|
|
115
|
+
return {
|
|
116
|
+
headers: { ...this.headers },
|
|
117
|
+
payload: this.serializePayload(this.payload)
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
serializePayload(payload) {
|
|
121
|
+
return payload;
|
|
122
|
+
}
|
|
123
|
+
asType(cls) {
|
|
124
|
+
const { headers, payload } = this.serialize();
|
|
125
|
+
return cls.from(payload, headers);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
function generateHeaderFor(cls, ...excludes) {
|
|
129
|
+
const headers = {};
|
|
130
|
+
if (!excludes.includes("id")) {
|
|
131
|
+
headers.id = v4();
|
|
132
|
+
}
|
|
133
|
+
if (!excludes.includes("type")) {
|
|
134
|
+
headers.type = cls.getType();
|
|
135
|
+
}
|
|
136
|
+
if (!excludes.includes("intent")) {
|
|
137
|
+
const intent = cls.getIntent();
|
|
138
|
+
if (intent !== void 0) {
|
|
139
|
+
headers.intent = intent;
|
|
7
140
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
141
|
+
}
|
|
142
|
+
if (!excludes.includes("schemaVersion")) {
|
|
143
|
+
const schemaVersion = cls.getSchemaVersion();
|
|
144
|
+
if (schemaVersion !== void 0) {
|
|
145
|
+
headers.schemaVersion = schemaVersion;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (!excludes.includes("createdAt")) {
|
|
149
|
+
headers.createdAt = /* @__PURE__ */ new Date();
|
|
150
|
+
}
|
|
151
|
+
return headers;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// src/domain/domain-event.ts
|
|
155
|
+
var DomainEvent = class extends Message {
|
|
156
|
+
static getIntent() {
|
|
157
|
+
return "event";
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// src/domain/identifiable.ts
|
|
162
|
+
var Id = class {
|
|
163
|
+
constructor(value) {
|
|
164
|
+
this.value = value;
|
|
165
|
+
}
|
|
166
|
+
getValue() {
|
|
167
|
+
return this.value;
|
|
168
|
+
}
|
|
169
|
+
equals(other) {
|
|
170
|
+
return this.constructor === other.constructor && this.getValue() === other.getValue();
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
// src/domain/repository.ts
|
|
175
|
+
var RepositoryError = class extends Error {
|
|
176
|
+
constructor(message) {
|
|
177
|
+
super(message);
|
|
178
|
+
this.name = "RepositoryError";
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
var DuplicateObjectError = class extends RepositoryError {
|
|
182
|
+
constructor(message) {
|
|
183
|
+
super(message);
|
|
184
|
+
this.name = "DuplicateObjectError";
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
var ObjectNotFoundError = class extends RepositoryError {
|
|
188
|
+
constructor(message) {
|
|
189
|
+
super(message);
|
|
190
|
+
this.name = "ObjectNotFoundError";
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// src/unit-of-work.ts
|
|
195
|
+
var Propagation = /* @__PURE__ */ ((Propagation2) => {
|
|
196
|
+
Propagation2["NEW"] = "new";
|
|
197
|
+
Propagation2["EXISTING"] = "existing";
|
|
198
|
+
Propagation2["NESTED"] = "nested";
|
|
199
|
+
return Propagation2;
|
|
200
|
+
})(Propagation || {});
|
|
201
|
+
|
|
202
|
+
export { AggregateRoot, DomainError, DomainEvent, DuplicateObjectError, Id, InvariantNotSatisfiedError, Message, ObjectNotFoundError, Propagation, RepositoryError, ValidationError };
|
|
203
|
+
//# sourceMappingURL=index.js.map
|
|
21
204
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,iDAA+B;AAC/B,4CAA0B;AAC1B,gDAA8B"}
|
|
1
|
+
{"version":3,"sources":["../src/domain/aggregate-root.ts","../src/domain/domain-error.ts","../src/message.ts","../src/domain/domain-event.ts","../src/domain/identifiable.ts","../src/domain/repository.ts","../src/unit-of-work.ts"],"names":["uuid","Propagation"],"mappings":"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","file":"index.js","sourcesContent":["import { DomainEvent } from \"./domain-event\";\nimport { Id, Identifiable } from \"./identifiable\";\n\nexport class AggregateRoot<T extends Id<string | number>>\n implements Identifiable<T>\n{\n protected events: DomainEvent[] = [];\n\n constructor(protected readonly id: T) {}\n\n public getId(): T {\n return this.id;\n }\n\n protected raise(event: DomainEvent): void {\n this.events.push(event);\n }\n\n public getEventsOccurred(): DomainEvent[] {\n return [...this.events];\n }\n}\n","export class DomainError extends Error {}\n\nexport class InvariantNotSatisfiedError extends DomainError {\n constructor(\n public readonly code: string,\n message: string = \"\"\n ) {\n super(message);\n this.name = \"InvariantNotSatisfiedError\";\n }\n}\n\nexport class ValidationError extends InvariantNotSatisfiedError {\n constructor(\n public readonly field: string,\n code: string,\n message: string = \"\"\n ) {\n super(code, message);\n\n this.name = \"ValidationError\";\n }\n}\n","import { v4 as uuid } from \"uuid\";\n\ntype Version = string | number | undefined;\n\nexport interface MessageHeaders {\n id: string;\n type: string;\n intent?: string;\n schemaVersion?: Version;\n createdAt: Date;\n\n [key: string]: unknown;\n}\n\ntype ExtraHeaderField = Exclude<\n keyof MessageHeaders,\n \"id\" | \"type\" | \"intent\" | \"schemaVersion\" | \"createdAt\"\n>;\n\ntype RawMessageHeaders = Omit<MessageHeaders, \"createdAt\"> & {\n createdAt: string | Date;\n};\n\nexport class Message<Payload = any> {\n protected headers!: MessageHeaders;\n\n public static getSchemaVersion(): Version {\n return (this as any).schemaVersion ?? undefined;\n }\n\n public static getType(): string {\n return (this as any).type ?? this.name;\n }\n\n public static getIntent(): string | undefined {\n return (this as any).intent ?? undefined;\n }\n\n protected static newHeaders(...excludes: string[]): MessageHeaders {\n return generateHeaderFor(this as any, ...excludes);\n }\n\n public static from(\n rawPayload: Record<string, unknown>,\n headers?: RawMessageHeaders\n ): Message {\n const payload = this.deserializeRawPayload(rawPayload);\n return new this(\n payload,\n headers ? this.deserializeRawHeaders(headers) : this.newHeaders()\n );\n }\n\n protected static deserializeRawPayload(rawPayload: any): any {\n return rawPayload;\n }\n\n protected static deserializeRawHeaders(\n headers: RawMessageHeaders\n ): MessageHeaders {\n headers.createdAt = new Date(headers.createdAt);\n\n return headers as MessageHeaders;\n }\n\n constructor(\n protected readonly payload: Payload,\n headers: Record<string, unknown> = {}\n ) {\n this.headers = Object.freeze(\n (this.constructor as any).mergeHeaders(headers)\n );\n\n if (payload && typeof payload === \"object\") {\n Object.freeze(payload);\n }\n }\n\n protected static mergeHeaders(\n headers: Record<string, unknown>\n ): MessageHeaders {\n return {\n ...this.newHeaders(...Object.keys(headers)),\n ...headers,\n };\n }\n\n public withHeader(field: ExtraHeaderField, value: unknown): this {\n const newHeaders = { ...this.headers, [field]: value };\n return new (this.constructor as any)(this.payload, newHeaders);\n }\n\n protected clone(): this {\n return new (this.constructor as any)(this.payload, { ...this.headers });\n }\n\n public getHeader<T = string>(field: string): T | undefined {\n return this.headers[field] as any;\n }\n\n public getHeaders(): MessageHeaders {\n return Object.freeze({ ...this.headers });\n }\n\n public getPayload(): Payload {\n return this.payload;\n }\n\n public getMessageId(): string {\n return this.headers.id;\n }\n\n public getMessageType(): string {\n return this.headers.type;\n }\n\n public getSchemaVersion(): Version | undefined {\n return this.headers.schemaVersion;\n }\n\n public getTimestamp(): Date {\n return this.headers.createdAt;\n }\n\n public getIntent(): string | undefined {\n return (this.constructor as MessageClass).getIntent();\n }\n\n public serialize(): {\n headers: MessageHeaders;\n payload: Record<string, unknown>;\n } {\n // we do this to convert the Date object to a string\n // and also to remove any reference to the original object\n return JSON.parse(JSON.stringify(this.doSerialize()));\n }\n\n private doSerialize(): {\n headers: MessageHeaders;\n payload: unknown;\n } {\n return {\n headers: { ...this.headers },\n payload: this.serializePayload(this.payload),\n };\n }\n\n protected serializePayload(payload: Payload): unknown {\n return payload;\n }\n\n public asType<M extends MessageClass>(cls: M): InstanceType<M> {\n const { headers, payload } = this.serialize();\n return cls.from(payload, headers) as InstanceType<M>;\n }\n}\n\nexport type AnyMessage = Message;\n\nexport type MessageClass<T extends Message = Message> = {\n getSchemaVersion(): Version;\n getType(): string;\n getIntent(): string | undefined;\n from: (rawPayload: any, header?: MessageHeaders) => T;\n new (...args: any[]): T;\n};\n\nfunction generateHeaderFor(\n cls: MessageClass,\n ...excludes: string[]\n): MessageHeaders {\n const headers: Partial<MessageHeaders> = {};\n\n if (!excludes.includes(\"id\")) {\n headers.id = uuid();\n }\n\n if (!excludes.includes(\"type\")) {\n headers.type = cls.getType();\n }\n\n if (!excludes.includes(\"intent\")) {\n const intent = cls.getIntent();\n if (intent !== undefined) {\n headers.intent = intent;\n }\n }\n\n if (!excludes.includes(\"schemaVersion\")) {\n const schemaVersion = cls.getSchemaVersion();\n if (schemaVersion !== undefined) {\n headers.schemaVersion = schemaVersion;\n }\n }\n\n if (!excludes.includes(\"createdAt\")) {\n headers.createdAt = new Date();\n }\n\n return headers as MessageHeaders;\n}\n\nexport type PayloadOf<M> = M extends Message<infer P> ? P : never;\n","import { Message } from \"@/message\";\n\nexport class DomainEvent<\n P extends Record<string, any> = Record<string, unknown>,\n> extends Message<P> {\n static override getIntent() {\n return \"event\";\n }\n}\n","export class Id<T extends string | number> {\n public constructor(private readonly value: T) {}\n\n public getValue(): T {\n return this.value;\n }\n\n public equals(other: Id<T>): boolean {\n return (\n this.constructor === other.constructor &&\n this.getValue() === other.getValue()\n );\n }\n}\n\nexport type IdOf<T> = T extends Identifiable<infer Id> ? Id : never;\n\nexport interface Identifiable<T extends Id<string | number> = Id<string>> {\n getId(): T;\n}\n","import { Identifiable, IdOf } from \"./identifiable\";\n\nexport interface Repository<T extends Identifiable<any>> {\n get(id: IdOf<T>): Promise<T>;\n add(entity: T): Promise<void>;\n update(entity: T): Promise<void>;\n}\n\nexport class RepositoryError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RepositoryError\";\n }\n}\n\nexport class DuplicateObjectError extends RepositoryError {\n constructor(message: string) {\n super(message);\n this.name = \"DuplicateObjectError\";\n }\n}\n\nexport class ObjectNotFoundError extends RepositoryError {\n constructor(message: string) {\n super(message);\n this.name = \"ObjectNotFoundError\";\n }\n}\n","export enum Propagation {\n NEW = \"new\",\n EXISTING = \"existing\",\n NESTED = \"nested\",\n}\n\nexport interface BaseUnitOfWorkOptions {\n propagation: Propagation;\n}\n\nexport interface UnitOfWork<\n Client = unknown,\n Options extends BaseUnitOfWorkOptions = BaseUnitOfWorkOptions,\n> {\n getClient(): Client;\n wrap<T>(\n fn: (client: Client) => Promise<T>,\n options?: Partial<Options>\n ): Promise<T>;\n}\n\n"]}
|
package/dist/test/index.d.ts
CHANGED
|
@@ -1,7 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { M as Message, b as MessageClass, c as MessageHeaders, E as EventStore, S as StoredEvent, a as EventStoreFetchResult } from '../event-store-BDib72ud.js';
|
|
2
|
+
|
|
3
|
+
declare function expectMessagesToBeFullyEqual(messages: Message[], expectedMessages: Message[]): void;
|
|
4
|
+
declare function expectMessagesToContain(messages: Message[], expectedMessages: Message[]): void;
|
|
5
|
+
declare function expectMessageToMatch(messages: Message[], messageType: string | MessageClass<any>, payload?: Record<string, unknown>): void;
|
|
6
|
+
|
|
7
|
+
declare const matchers_expectMessageToMatch: typeof expectMessageToMatch;
|
|
8
|
+
declare const matchers_expectMessagesToBeFullyEqual: typeof expectMessagesToBeFullyEqual;
|
|
9
|
+
declare const matchers_expectMessagesToContain: typeof expectMessagesToContain;
|
|
10
|
+
declare namespace matchers {
|
|
11
|
+
export { matchers_expectMessageToMatch as expectMessageToMatch, matchers_expectMessagesToBeFullyEqual as expectMessagesToBeFullyEqual, matchers_expectMessagesToContain as expectMessagesToContain };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare class DummyMessage extends Message<Record<never, never>> {
|
|
15
|
+
static type: string;
|
|
16
|
+
static create(): DummyMessage;
|
|
17
|
+
static createMany(number: number): DummyMessage[];
|
|
18
|
+
static from(_: Record<never, never>, headers?: MessageHeaders): DummyMessage;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare function setExpect(expectStatic: any): void;
|
|
22
|
+
|
|
23
|
+
declare function partialMatch(source: Record<any, any>, target: Record<any, any>): boolean;
|
|
24
|
+
|
|
25
|
+
declare function waitForTicks(number?: number): Promise<void>;
|
|
26
|
+
declare function waitForMs(number?: number): Promise<void>;
|
|
27
|
+
declare function waitFor(type?: "ticks" | "ms", number?: number): Promise<void>;
|
|
28
|
+
|
|
29
|
+
declare class InMemoryEventStore implements EventStore {
|
|
30
|
+
private events;
|
|
31
|
+
store(event: Message): Promise<StoredEvent>;
|
|
32
|
+
storeAll(events: Message[]): Promise<StoredEvent[]>;
|
|
33
|
+
fetch(afterPosition: number, limit?: number): Promise<EventStoreFetchResult>;
|
|
34
|
+
getLastPosition(): Promise<number>;
|
|
35
|
+
clear(): void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { DummyMessage, InMemoryEventStore, expectMessageToMatch, expectMessagesToBeFullyEqual, expectMessagesToContain, matchers, partialMatch, setExpect, waitFor, waitForMs, waitForTicks };
|