-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathmain.js
More file actions
110 lines (88 loc) · 2.49 KB
/
Copy pathmain.js
File metadata and controls
110 lines (88 loc) · 2.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
(function () {
const out = document.getElementById('out');
function write(line) {
out.textContent = `${out.textContent}\n${line}`;
}
function setStatusOk() {
out.classList.remove('fail');
out.classList.add('ok');
}
function setStatusFail() {
out.classList.remove('ok');
out.classList.add('fail');
}
if (!globalThis.Cqrs)
throw new Error('Cqrs bundle is not loaded. Run `npm run build:browser` first.');
const {
AbstractAggregate,
AbstractProjection,
ContainerBuilder,
InMemoryEventStorage
} = globalThis.Cqrs;
class UserAggregateState {
userCreated(event) {
this.password = event.payload.password;
}
passwordChanged(event) {
this.password = event.payload.newPassword;
}
}
class UserAggregate extends AbstractAggregate {
constructor(params) {
super(params);
this.state = new UserAggregateState();
}
createUser(payload) {
this.emit('userCreated', {
username: payload.username,
password: payload.password
});
}
changePassword(payload) {
if (payload.oldPassword !== this.state.password)
throw new Error('Invalid password');
this.emit('passwordChanged', {
newPassword: payload.newPassword
});
}
}
class UsersProjection extends AbstractProjection {
constructor() {
super();
this.view = new Map();
}
userCreated(event) {
this.view.set(event.aggregateId, { username: event.payload.username });
}
}
async function main() {
out.textContent = '';
write('Building container…');
const builder = new ContainerBuilder();
// auto-resolved as eventStorageReader, eventStorage, and identifierProvider
builder.register(InMemoryEventStorage);
builder.registerAggregate(UserAggregate);
builder.registerProjection(UsersProjection, 'users');
const container = builder.container();
const { users, commandBus } = container;
write('Sending commands…');
const [userCreated] = await commandBus.send('createUser', undefined, {
payload: { username: 'john', password: 'magic' },
context: {}
});
await commandBus.send('changePassword', userCreated.aggregateId, {
payload: { oldPassword: 'magic', newPassword: 'no magic' },
context: {}
});
const user = users.get(userCreated.aggregateId);
if (!user || user.username !== 'john')
throw new Error(`Unexpected user view value: ${JSON.stringify(user)}`);
write(`OK: ${JSON.stringify(user)}`);
setStatusOk();
}
main().catch(err => {
console.error(err);
out.textContent = `FAILED: ${err?.message ?? String(err)}`;
setStatusFail();
});
}());