Skip to content

Commit 28f7269

Browse files
authored
Merge pull request #101 from dolittle/type-registration-rules
Type registration rules
2 parents ca3d1c5 + f4d1dd8 commit 28f7269

236 files changed

Lines changed: 4156 additions & 1688 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Samples/Tutorials/Aggregates/DishHandler.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,21 @@
33

44
// Sample code for the tutorial at https://dolittle.io/tutorials/aggregates/
55

6+
import { inject } from '@dolittle/sdk.dependencyinversion';
67
import { EventContext } from '@dolittle/sdk.events';
78
import { eventHandler, handles } from '@dolittle/sdk.events.handling';
9+
import { Logger } from 'winston';
10+
811
import { DishPrepared } from './DishPrepared';
912

1013
@eventHandler('f2d366cf-c00a-4479-acc4-851e04b6fbba')
1114
export class DishHandler {
15+
constructor(
16+
@inject('Logger') private readonly _logger: Logger
17+
) {}
1218

1319
@handles(DishPrepared)
14-
dishPrepared(event: DishPrepared, eventContext: EventContext) {
15-
console.log(`${event.Chef} has prepared ${event.Dish}. Yummm!`);
20+
async dishPrepared(event: DishPrepared, eventContext: EventContext) {
21+
this._logger.info(`${event.Chef} has prepared ${event.Dish}. Yummm!`);
1622
}
1723
}

Samples/Tutorials/Aggregates/Kitchen.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import { aggregateRoot, AggregateRoot, on } from '@dolittle/sdk.aggregates';
77
import { EventSourceId } from '@dolittle/sdk.events';
8+
89
import { DishPrepared } from './DishPrepared';
910

1011
@aggregateRoot('01ad9a9f-711f-47a8-8549-43320f782a1e')

Samples/Tutorials/Aggregates/index.ts

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,17 @@
55

66
import { DolittleClient } from '@dolittle/sdk';
77
import { TenantId } from '@dolittle/sdk.execution';
8-
import { DishPrepared } from './DishPrepared';
9-
import { DishHandler } from './DishHandler';
8+
9+
import './DishHandler';
1010
import { Kitchen } from './Kitchen';
1111

1212
(async () => {
1313
const client = await DolittleClient
14-
.setup(builder => builder
15-
.withEventTypes(eventTypes =>
16-
eventTypes.register(DishPrepared))
17-
.withEventHandlers(builder =>
18-
builder.registerEventHandler(DishHandler))
19-
.withAggregateRoots(aggregateRoots =>
20-
aggregateRoots.register(Kitchen)))
14+
.setup()
2115
.connect();
2216

23-
// TODO: aggregates
24-
// await client
25-
// .aggregateOf(Kitchen, 'Dolittle Tacos', _ => _.forTenant(TenantId.development))
26-
// .perform(kitchen => kitchen.prepareDish('Bean Blaster Taco', 'Mr. Taco'));
27-
28-
console.log('Done');
17+
await client.aggregates
18+
.forTenant(TenantId.development)
19+
.get(Kitchen, 'Dolittle Tacos')
20+
.perform(kitchen => kitchen.prepareDish('Bean Blaster Taco', 'Mr. Taco'));
2921
})();
30-
setInterval(function () {
31-
}, 1000 * 60 * 60);

Samples/Tutorials/Embeddings/Employee.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import { CouldNotResolveUpdateToEvents, embedding, EmbeddingContext, EmbeddingProjectContext, on, resolveDeletionToEvents, resolveUpdateToEvents } from '@dolittle/sdk.embeddings';
77
import { ProjectionResult } from '@dolittle/sdk.projections';
8+
89
import { EmployeeHired } from './EmployeeHired';
910
import { EmployeeRetired } from './EmployeeRetired';
1011
import { EmployeeTransferred } from './EmployeeTransferred';

Samples/Tutorials/Embeddings/index.ts

Lines changed: 29 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,49 +5,40 @@
55

66
import { DolittleClient } from '@dolittle/sdk';
77
import { TenantId } from '@dolittle/sdk.execution';
8+
import { setTimeout } from 'timers/promises';
9+
810
import { Employee } from './Employee';
9-
import { EmployeeHired } from './EmployeeHired';
10-
import { EmployeeRetired } from './EmployeeRetired';
11-
import { EmployeeTransferred } from './EmployeeTransferred';
1211

1312
(async () => {
1413
const client = await DolittleClient
15-
.setup(builder => builder
16-
.withEventTypes(eventTypes => {
17-
eventTypes.register(EmployeeHired);
18-
eventTypes.register(EmployeeTransferred);
19-
eventTypes.register(EmployeeRetired);
20-
})
21-
.withEmbeddings(builder => {
22-
builder.registerEmbedding(Employee);
23-
}))
14+
.setup()
2415
.connect();
2516

2617
// wait for the registration to complete
27-
setTimeout(async () => {
28-
// mock of the state from the external HR system
29-
const updatedEmployee = new Employee(
30-
'Mr. Taco',
31-
'Street Food Taco Truck');
32-
33-
await client.embeddings
34-
.forTenant(TenantId.development)
35-
.update(Employee, updatedEmployee.name, updatedEmployee);
36-
console.log(`Updated ${updatedEmployee.name}`);
37-
38-
const mrTaco = await client.embeddings
39-
.forTenant(TenantId.development)
40-
.get(Employee, 'Mr. Taco');
41-
console.log(`Mr. Taco is now working at ${mrTaco.state.workplace}`);
42-
43-
const allEmployeeNames = await client.embeddings
44-
.forTenant(TenantId.development)
45-
.getKeys(Employee);
46-
console.log(`All current employees are ${allEmployeeNames}`);
47-
48-
await client.embeddings
49-
.forTenant(TenantId.development)
50-
.delete(Employee, updatedEmployee.name);
51-
console.log(`Deleted ${updatedEmployee.name}`);
52-
}, 1000);
18+
await setTimeout(1000);
19+
20+
// mock of the state from the external HR system
21+
const updatedEmployee = new Employee(
22+
'Mr. Taco',
23+
'Street Food Taco Truck');
24+
25+
await client.embeddings
26+
.forTenant(TenantId.development)
27+
.update(Employee, updatedEmployee.name, updatedEmployee);
28+
console.log(`Updated ${updatedEmployee.name}`);
29+
30+
const mrTaco = await client.embeddings
31+
.forTenant(TenantId.development)
32+
.get(Employee, 'Mr. Taco');
33+
console.log(`Mr. Taco is now working at ${mrTaco.state.workplace}`);
34+
35+
const allEmployeeNames = await client.embeddings
36+
.forTenant(TenantId.development)
37+
.getKeys(Employee);
38+
console.log(`All current employees are ${allEmployeeNames}`);
39+
40+
await client.embeddings
41+
.forTenant(TenantId.development)
42+
.delete(Employee, updatedEmployee.name);
43+
console.log(`Deleted ${updatedEmployee.name}`);
5344
})();

Samples/Tutorials/GettingStarted/DishHandler.ts

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,21 @@
33

44
// Sample code for the tutorial at https://dolittle.io/tutorials/getting-started/typescript/
55

6-
import { Logger } from 'winston';
76
import { inject } from '@dolittle/sdk.dependencyinversion';
8-
import { EventContext, IEventStore } from '@dolittle/sdk.events';
7+
import { EventContext } from '@dolittle/sdk.events';
98
import { eventHandler, handles } from '@dolittle/sdk.events.handling';
9+
import { Logger } from 'winston';
10+
1011
import { DishPrepared } from './DishPrepared';
1112

1213
@eventHandler('f2d366cf-c00a-4479-acc4-851e04b6fbba')
13-
@inject('logger', IEventStore)
1414
export class DishHandler {
15-
1615
constructor(
17-
// @inject('logger') private readonly _logger: Logger,
18-
// @inject(IEventStore) private readonly _eventStore: IEventStore,
19-
private readonly _logger: Logger,
20-
private readonly _eventStore: IEventStore,
16+
@inject('Logger') private readonly _logger: Logger
2117
) {}
2218

2319
@handles(DishPrepared)
2420
async dishPrepared(event: DishPrepared, eventContext: EventContext) {
25-
console.log(`${event.Chef} has prepared ${event.Dish}. Yummm!`);
26-
this._logger.info('Hello nice message from the eventhandler');
27-
28-
await new Promise<void>((resolve) => {
29-
setTimeout(async () => {
30-
await this._eventStore.commit(new DishPrepared('EventHandlerChef', 'RecursiveDish'), 'Dakitchen');
31-
resolve();
32-
}, 1000);
33-
});
34-
35-
this._logger.info('Committed new event');
21+
this._logger.info(`${event.Chef} has prepared ${event.Dish}. Yummm!`);
3622
}
3723
}

Samples/Tutorials/GettingStarted/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
import { DolittleClient } from '@dolittle/sdk';
77
import { TenantId } from '@dolittle/sdk.execution';
8-
import { DishPrepared } from './DishPrepared';
8+
99
import './DishHandler';
10+
import { DishPrepared } from './DishPrepared';
1011

1112
(async () => {
1213
const client = await DolittleClient

Samples/Tutorials/Projections/DishCounter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// Sample code for the tutorial at https://dolittle.io/tutorials/projections/typescript/
55

66
import { ProjectionContext, projection, on } from '@dolittle/sdk.projections';
7+
78
import { DishPrepared } from './DishPrepared';
89

910
@projection('98f9db66-b6ca-4e5f-9fc3-638626c9ecfa')

Samples/Tutorials/Projections/index.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,16 @@
55

66
import { DolittleClient } from '@dolittle/sdk';
77
import { TenantId } from '@dolittle/sdk.execution';
8-
import { DishPrepared } from './DishPrepared';
9-
import { DishCounter } from './DishCounter';
8+
import { setTimeout } from 'timers/promises';
9+
1010
import { Chef } from './Chef';
11+
import { DishCounter } from './DishCounter';
12+
import { DishPrepared } from './DishPrepared';
1113

1214
(async () => {
1315
const client = await DolittleClient
1416
.setup(builder => builder
15-
.withEventTypes(eventTypes =>
16-
eventTypes.register(DishPrepared))
1717
.withProjections(builder => {
18-
builder.registerProjection(DishCounter);
19-
2018
builder.createProjection('0767bc04-bc03-40b8-a0be-5f6c6130f68b')
2119
.forReadModel(Chef)
2220
.on(DishPrepared, _ => _.keyFromProperty('Chef'), (chef, event, projectionContext) => {
@@ -34,12 +32,12 @@ import { Chef } from './Chef';
3432
await eventStore.commit(new DishPrepared('Avocado Artillery Tortilla', 'Mr. Taco'), 'Dolittle Tacos');
3533
await eventStore.commit(new DishPrepared('Chili Canon Wrap', 'Mrs. Tex Mex'), 'Dolittle Tacos');
3634

37-
setTimeout(async () => {
38-
for (const [dish, { state: counter }] of await client.projections.forTenant(TenantId.development).getAll(DishCounter)) {
39-
console.log(`The kitchen has prepared ${dish} ${counter.numberOfTimesPrepared} times`);
40-
}
35+
await setTimeout(1000);
36+
37+
for (const [dish, { state: counter }] of await client.projections.forTenant(TenantId.development).getAll(DishCounter)) {
38+
console.log(`The kitchen has prepared ${dish} ${counter.numberOfTimesPrepared} times`);
39+
}
4140

42-
const chef = await client.projections.forTenant(TenantId.development).get<Chef>(Chef, 'Mrs. Tex Mex');
43-
console.log(`${chef.key} has prepared ${chef.state.dishes}`);
44-
}, 1000);
41+
const chef = await client.projections.forTenant(TenantId.development).get<Chef>(Chef, 'Mrs. Tex Mex');
42+
console.log(`${chef.key} has prepared ${chef.state.dishes}`);
4543
})();

Source/aggregates/AggregateOf.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
import { Logger } from 'winston';
55
import { Constructor } from '@dolittle/types';
66

7-
import { EventSourceId, IEventStore, IEventTypes } from '@dolittle/sdk.events';
7+
import { EventSourceId, EventSourceIdLike, IEventStore, IEventTypes } from '@dolittle/sdk.events';
88

99
import { AggregateRoot } from './AggregateRoot';
1010
import { AggregateRootOperations } from './AggregateRootOperations';
11+
import { AggregateRootType } from './AggregateRootType';
1112
import { IAggregateOf } from './IAggregateOf';
1213
import { IAggregateRootOperations } from './IAggregateRootOperations';
1314

@@ -19,13 +20,15 @@ export class AggregateOf<TAggregateRoot extends AggregateRoot> extends IAggregat
1920

2021
/**
2122
* Initialises a new instance of the {@link AggregateOf} class.
22-
* @param {Constructor<TAggregateRoot>} _type - The type of the aggregate root implementation.
23+
* @param {Constructor<TAggregateRoot>} _type - The class implementing the aggregate root.
24+
* @param {AggregateRootType} _aggregateRootType - The aggregate root type associated with the aggregate root.
2325
* @param {IEventStore} _eventStore - The event store to fetch committed events from and commit aggregate events with.
2426
* @param {IEventTypes} _eventTypes - All registered event types.
2527
* @param {Logger} _logger - The logger to use for logging.
2628
*/
2729
constructor(
2830
private readonly _type: Constructor<TAggregateRoot>,
31+
private readonly _aggregateRootType: AggregateRootType,
2932
private readonly _eventStore: IEventStore,
3033
private readonly _eventTypes: IEventTypes,
3134
private readonly _logger: Logger) {
@@ -38,7 +41,13 @@ export class AggregateOf<TAggregateRoot extends AggregateRoot> extends IAggregat
3841
}
3942

4043
/** @inheritdoc */
41-
get(eventSourceId: EventSourceId): IAggregateRootOperations<TAggregateRoot> {
42-
return new AggregateRootOperations<TAggregateRoot>(eventSourceId, this._eventStore, this._type, this._eventTypes, this._logger);
44+
get(eventSourceId: EventSourceIdLike): IAggregateRootOperations<TAggregateRoot> {
45+
return new AggregateRootOperations<TAggregateRoot>(
46+
this._type,
47+
this._aggregateRootType,
48+
EventSourceId.from(eventSourceId),
49+
this._eventStore,
50+
this._eventTypes,
51+
this._logger);
4352
}
4453
}

0 commit comments

Comments
 (0)