@hexaijs/core 0.4.0 → 0.5.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.
- package/README.md +79 -0
- package/dist/{message.d.ts → event-store-DQXtakLF.d.ts} +28 -9
- package/dist/index.d.ts +67 -5
- package/dist/index.js +212 -19
- package/dist/index.js.map +1 -1
- package/dist/test/index.d.ts +38 -7
- package/dist/test/index.js +314 -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
package/README.md
CHANGED
|
@@ -51,6 +51,84 @@ command.getPayload(); // the typed payload object
|
|
|
51
51
|
|
|
52
52
|
Every message automatically receives headers including a unique ID and timestamp. The `type` static property follows the convention `"bounded-context.message-name"`.
|
|
53
53
|
|
|
54
|
+
#### MessageOptions
|
|
55
|
+
|
|
56
|
+
The constructor accepts an optional `MessageOptions` object for passing custom headers:
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
interface MessageOptions {
|
|
60
|
+
headers?: Record<string, unknown>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Pass custom headers
|
|
64
|
+
const command = new CreateOrderCommand(
|
|
65
|
+
{ customerId: "customer-123", items: [] },
|
|
66
|
+
{ headers: { correlationId: "corr-abc" } }
|
|
67
|
+
);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
#### Serialization
|
|
71
|
+
|
|
72
|
+
Messages provide two serialization methods:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// toJSON() - preserves Date objects, suitable for structured output
|
|
76
|
+
const json = command.toJSON();
|
|
77
|
+
// { headers: { id, type, createdAt: Date, ... }, payload: { ... } }
|
|
78
|
+
|
|
79
|
+
// serialize() - fully serialized plain object (dates become strings)
|
|
80
|
+
const plain = command.serialize();
|
|
81
|
+
// { headers: { id, type, createdAt: "2026-...", ... }, payload: { ... } }
|
|
82
|
+
|
|
83
|
+
// JSON.stringify uses toJSON() automatically
|
|
84
|
+
JSON.stringify(command);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Override `serializePayload()` to customize how the payload is serialized:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
class MyEvent extends DomainEvent<{ date: Temporal.PlainDate }> {
|
|
91
|
+
protected serializePayload(payload: { date: Temporal.PlainDate }) {
|
|
92
|
+
return { date: payload.date.toString() };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### Deserialization
|
|
98
|
+
|
|
99
|
+
Use the static `from()` method to reconstruct a message from serialized data:
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
const raw = { customerId: "c-123", items: [] };
|
|
103
|
+
const headers = { id: "msg-1", type: "order.create-order", createdAt: "2026-01-01T00:00:00Z" };
|
|
104
|
+
|
|
105
|
+
const command = CreateOrderCommand.from(raw, headers);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Override `deserializeRawPayload()` for custom deserialization:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
class MyEvent extends DomainEvent<{ date: Temporal.PlainDate }> {
|
|
112
|
+
protected static deserializeRawPayload(raw: any) {
|
|
113
|
+
return { date: Temporal.PlainDate.from(raw.date) };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### Fluent Header API
|
|
119
|
+
|
|
120
|
+
Use `withHeader()` to create a new message instance with an additional header:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
const command = new CreateOrderCommand({ customerId: "c-123", items: [] })
|
|
124
|
+
.withHeader("correlationId", "corr-abc")
|
|
125
|
+
.withHeader("source", "api-gateway");
|
|
126
|
+
|
|
127
|
+
command.getHeader("correlationId"); // "corr-abc"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`withHeader()` returns a new immutable instance - the original message is not modified.
|
|
131
|
+
|
|
54
132
|
### DomainEvent
|
|
55
133
|
|
|
56
134
|
`DomainEvent` extends `Message` for events that represent something that happened in your domain.
|
|
@@ -257,6 +335,7 @@ throw new DuplicateObjectError("Order with this ID already exists");
|
|
|
257
335
|
| Export | Description |
|
|
258
336
|
|--------|-------------|
|
|
259
337
|
| `Message<P>` | Base message class with headers and typed payload |
|
|
338
|
+
| `MessageOptions` | Options for Message constructor (`{ headers? }`) |
|
|
260
339
|
| `DomainEvent<P>` | Message subclass for domain events |
|
|
261
340
|
| `AggregateRoot<T>` | Base class for aggregates with event collection |
|
|
262
341
|
| `Id<T>` | Value object for typed identities |
|
|
@@ -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,10 @@ type ExtraHeaderField = Exclude<keyof MessageHeaders, "id" | "type" | "intent" |
|
|
|
11
11
|
type RawMessageHeaders = Omit<MessageHeaders, "createdAt"> & {
|
|
12
12
|
createdAt: string | Date;
|
|
13
13
|
};
|
|
14
|
-
|
|
14
|
+
interface MessageOptions {
|
|
15
|
+
headers?: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
declare class Message<Payload = any> {
|
|
15
18
|
protected readonly payload: Payload;
|
|
16
19
|
protected headers: MessageHeaders;
|
|
17
20
|
static getSchemaVersion(): Version;
|
|
@@ -21,10 +24,11 @@ export declare class Message<Payload = any> {
|
|
|
21
24
|
static from(rawPayload: Record<string, unknown>, headers?: RawMessageHeaders): Message;
|
|
22
25
|
protected static deserializeRawPayload(rawPayload: any): any;
|
|
23
26
|
protected static deserializeRawHeaders(headers: RawMessageHeaders): MessageHeaders;
|
|
24
|
-
constructor(payload: Payload,
|
|
27
|
+
constructor(payload: Payload, options?: MessageOptions);
|
|
25
28
|
protected static mergeHeaders(headers: Record<string, unknown>): MessageHeaders;
|
|
26
29
|
withHeader(field: ExtraHeaderField, value: unknown): this;
|
|
27
30
|
protected clone(): this;
|
|
31
|
+
protected cloneWithHeaders(headers: Record<string, unknown>): this;
|
|
28
32
|
getHeader<T = string>(field: string): T | undefined;
|
|
29
33
|
getHeaders(): MessageHeaders;
|
|
30
34
|
getPayload(): Payload;
|
|
@@ -33,22 +37,37 @@ export declare class Message<Payload = any> {
|
|
|
33
37
|
getSchemaVersion(): Version | undefined;
|
|
34
38
|
getTimestamp(): Date;
|
|
35
39
|
getIntent(): string | undefined;
|
|
40
|
+
toJSON(): {
|
|
41
|
+
headers: MessageHeaders;
|
|
42
|
+
payload: unknown;
|
|
43
|
+
};
|
|
36
44
|
serialize(): {
|
|
37
45
|
headers: MessageHeaders;
|
|
38
46
|
payload: Record<string, unknown>;
|
|
39
47
|
};
|
|
40
|
-
private doSerialize;
|
|
41
48
|
protected serializePayload(payload: Payload): unknown;
|
|
42
49
|
asType<M extends MessageClass>(cls: M): InstanceType<M>;
|
|
43
50
|
}
|
|
44
|
-
|
|
45
|
-
|
|
51
|
+
type AnyMessage = Message;
|
|
52
|
+
type MessageClass<T extends Message = Message> = {
|
|
46
53
|
getSchemaVersion(): Version;
|
|
47
54
|
getType(): string;
|
|
48
55
|
getIntent(): string | undefined;
|
|
49
56
|
from: (rawPayload: any, header?: MessageHeaders) => T;
|
|
50
57
|
new (...args: any[]): T;
|
|
51
58
|
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
type PayloadOf<M> = M extends Message<infer P> ? P : never;
|
|
60
|
+
|
|
61
|
+
interface StoredEvent {
|
|
62
|
+
position: number;
|
|
63
|
+
event: Message;
|
|
64
|
+
}
|
|
65
|
+
interface EventStoreFetchResult {
|
|
66
|
+
events: StoredEvent[];
|
|
67
|
+
lastPosition: number;
|
|
68
|
+
}
|
|
69
|
+
interface EventStore {
|
|
70
|
+
fetch(afterPosition: number, limit?: number): Promise<EventStoreFetchResult>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
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, type MessageOptions as d };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,67 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { M as Message } from './event-store-DQXtakLF.js';
|
|
2
|
+
export { A as AnyMessage, E as EventStore, a as EventStoreFetchResult, b as MessageClass, c as MessageHeaders, d as MessageOptions, P as PayloadOf, S as StoredEvent } from './event-store-DQXtakLF.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,214 @@
|
|
|
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, options) {
|
|
39
|
+
this.payload = payload;
|
|
40
|
+
this.headers = Object.freeze(
|
|
41
|
+
this.constructor.mergeHeaders(options?.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(payload, {
|
|
63
|
+
headers: headers ? this.deserializeRawHeaders(headers) : this.newHeaders()
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
static deserializeRawPayload(rawPayload) {
|
|
67
|
+
return rawPayload;
|
|
68
|
+
}
|
|
69
|
+
static deserializeRawHeaders(headers) {
|
|
70
|
+
headers.createdAt = new Date(headers.createdAt);
|
|
71
|
+
return headers;
|
|
72
|
+
}
|
|
73
|
+
static mergeHeaders(headers) {
|
|
74
|
+
return {
|
|
75
|
+
...this.newHeaders(...Object.keys(headers)),
|
|
76
|
+
...headers
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
withHeader(field, value) {
|
|
80
|
+
const newHeaders = { ...this.headers, [field]: value };
|
|
81
|
+
return this.cloneWithHeaders(newHeaders);
|
|
82
|
+
}
|
|
83
|
+
clone() {
|
|
84
|
+
const cloned = Object.create(Object.getPrototypeOf(this));
|
|
85
|
+
Object.assign(cloned, this);
|
|
86
|
+
return cloned;
|
|
87
|
+
}
|
|
88
|
+
cloneWithHeaders(headers) {
|
|
89
|
+
const cloned = this.clone();
|
|
90
|
+
Object.defineProperty(cloned, "headers", {
|
|
91
|
+
value: Object.freeze(headers),
|
|
92
|
+
writable: false,
|
|
93
|
+
configurable: true
|
|
94
|
+
});
|
|
95
|
+
return cloned;
|
|
96
|
+
}
|
|
97
|
+
getHeader(field) {
|
|
98
|
+
return this.headers[field];
|
|
99
|
+
}
|
|
100
|
+
getHeaders() {
|
|
101
|
+
return Object.freeze({ ...this.headers });
|
|
102
|
+
}
|
|
103
|
+
getPayload() {
|
|
104
|
+
return this.payload;
|
|
105
|
+
}
|
|
106
|
+
getMessageId() {
|
|
107
|
+
return this.headers.id;
|
|
108
|
+
}
|
|
109
|
+
getMessageType() {
|
|
110
|
+
return this.headers.type;
|
|
111
|
+
}
|
|
112
|
+
getSchemaVersion() {
|
|
113
|
+
return this.headers.schemaVersion;
|
|
114
|
+
}
|
|
115
|
+
getTimestamp() {
|
|
116
|
+
return this.headers.createdAt;
|
|
117
|
+
}
|
|
118
|
+
getIntent() {
|
|
119
|
+
return this.constructor.getIntent();
|
|
120
|
+
}
|
|
121
|
+
toJSON() {
|
|
122
|
+
return {
|
|
123
|
+
headers: { ...this.headers },
|
|
124
|
+
payload: this.serializePayload(this.payload)
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
serialize() {
|
|
128
|
+
return JSON.parse(JSON.stringify(this.toJSON()));
|
|
129
|
+
}
|
|
130
|
+
serializePayload(payload) {
|
|
131
|
+
return payload;
|
|
132
|
+
}
|
|
133
|
+
asType(cls) {
|
|
134
|
+
const { headers, payload } = this.serialize();
|
|
135
|
+
return cls.from(payload, headers);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
function generateHeaderFor(cls, ...excludes) {
|
|
139
|
+
const headers = {};
|
|
140
|
+
if (!excludes.includes("id")) {
|
|
141
|
+
headers.id = v4();
|
|
142
|
+
}
|
|
143
|
+
if (!excludes.includes("type")) {
|
|
144
|
+
headers.type = cls.getType();
|
|
145
|
+
}
|
|
146
|
+
if (!excludes.includes("intent")) {
|
|
147
|
+
const intent = cls.getIntent();
|
|
148
|
+
if (intent !== void 0) {
|
|
149
|
+
headers.intent = intent;
|
|
7
150
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
151
|
+
}
|
|
152
|
+
if (!excludes.includes("schemaVersion")) {
|
|
153
|
+
const schemaVersion = cls.getSchemaVersion();
|
|
154
|
+
if (schemaVersion !== void 0) {
|
|
155
|
+
headers.schemaVersion = schemaVersion;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (!excludes.includes("createdAt")) {
|
|
159
|
+
headers.createdAt = /* @__PURE__ */ new Date();
|
|
160
|
+
}
|
|
161
|
+
return headers;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/domain/domain-event.ts
|
|
165
|
+
var DomainEvent = class extends Message {
|
|
166
|
+
static getIntent() {
|
|
167
|
+
return "event";
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
// src/domain/identifiable.ts
|
|
172
|
+
var Id = class {
|
|
173
|
+
constructor(value) {
|
|
174
|
+
this.value = value;
|
|
175
|
+
}
|
|
176
|
+
getValue() {
|
|
177
|
+
return this.value;
|
|
178
|
+
}
|
|
179
|
+
equals(other) {
|
|
180
|
+
return this.constructor === other.constructor && this.getValue() === other.getValue();
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// src/domain/repository.ts
|
|
185
|
+
var RepositoryError = class extends Error {
|
|
186
|
+
constructor(message) {
|
|
187
|
+
super(message);
|
|
188
|
+
this.name = "RepositoryError";
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
var DuplicateObjectError = class extends RepositoryError {
|
|
192
|
+
constructor(message) {
|
|
193
|
+
super(message);
|
|
194
|
+
this.name = "DuplicateObjectError";
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
var ObjectNotFoundError = class extends RepositoryError {
|
|
198
|
+
constructor(message) {
|
|
199
|
+
super(message);
|
|
200
|
+
this.name = "ObjectNotFoundError";
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
// src/unit-of-work.ts
|
|
205
|
+
var Propagation = /* @__PURE__ */ ((Propagation2) => {
|
|
206
|
+
Propagation2["NEW"] = "new";
|
|
207
|
+
Propagation2["EXISTING"] = "existing";
|
|
208
|
+
Propagation2["NESTED"] = "nested";
|
|
209
|
+
return Propagation2;
|
|
210
|
+
})(Propagation || {});
|
|
211
|
+
|
|
212
|
+
export { AggregateRoot, DomainError, DomainEvent, DuplicateObjectError, Id, InvariantNotSatisfiedError, Message, ObjectNotFoundError, Propagation, RepositoryError, ValidationError };
|
|
213
|
+
//# sourceMappingURL=index.js.map
|
|
21
214
|
//# 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 interface MessageOptions {\n headers?: Record<string, unknown>;\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(payload, {\n headers: headers\n ? this.deserializeRawHeaders(headers)\n : 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 options?: MessageOptions\n ) {\n this.headers = Object.freeze(\n (this.constructor as any).mergeHeaders(options?.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 this.cloneWithHeaders(newHeaders);\n }\n\n protected clone(): this {\n const cloned = Object.create(Object.getPrototypeOf(this));\n Object.assign(cloned, this);\n return cloned;\n }\n\n protected cloneWithHeaders(headers: Record<string, unknown>): this {\n const cloned = this.clone();\n Object.defineProperty(cloned, \"headers\", {\n value: Object.freeze(headers),\n writable: false,\n configurable: true,\n });\n return cloned;\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 toJSON(): {\n headers: MessageHeaders;\n payload: unknown;\n } {\n return {\n headers: { ...this.headers },\n payload: this.serializePayload(this.payload),\n };\n }\n\n public serialize(): {\n headers: MessageHeaders;\n payload: Record<string, unknown>;\n } {\n return JSON.parse(JSON.stringify(this.toJSON()));\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-DQXtakLF.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 };
|