Skip to content

Commit 9879c4c

Browse files
committed
space: Don't maintain leavers within the members array
In preparation for removing the members array in favour of loading members directly from the presenceMap (see https://ably.atlassian.net/browse/MMB-182). Signed-off-by: Lewis Marshall <[email protected]>
1 parent e731350 commit 9879c4c

File tree

3 files changed

+32
-28
lines changed

3 files changed

+32
-28
lines changed

src/Leavers.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { SpaceMember } from './types.js';
22

3-
type SpaceLeaver = SpaceMember & {
3+
type SpaceLeaver = {
4+
member: SpaceMember;
45
timeoutId: ReturnType<typeof setTimeout>;
56
};
67

@@ -10,21 +11,25 @@ class Leavers {
1011
constructor(private offlineTimeout: number) {}
1112

1213
getByConnectionId(connectionId: string): SpaceLeaver | undefined {
13-
return this.leavers.find((leaver) => leaver.connectionId === connectionId);
14+
return this.leavers.find((leaver) => leaver.member.connectionId === connectionId);
15+
}
16+
17+
getAll(): SpaceLeaver[] {
18+
return this.leavers;
1419
}
1520

1621
addLeaver(member: SpaceMember, timeoutCallback: () => void) {
1722
// remove any existing leaver to prevent old timers from firing
1823
this.removeLeaver(member.connectionId);
1924

2025
this.leavers.push({
21-
...member,
26+
member,
2227
timeoutId: setTimeout(timeoutCallback, this.offlineTimeout),
2328
});
2429
}
2530

2631
removeLeaver(connectionId: string) {
27-
const leaverIndex = this.leavers.findIndex((leaver) => leaver.connectionId === connectionId);
32+
const leaverIndex = this.leavers.findIndex((leaver) => leaver.member.connectionId === connectionId);
2833

2934
if (leaverIndex >= 0) {
3035
clearTimeout(this.leavers[leaverIndex].timeoutId);

src/Members.ts

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,25 @@ class Members extends EventEmitter<MemberEventsMap> {
3131
processPresenceMessage(message: PresenceMember) {
3232
const { action, connectionId } = message;
3333
const isLeaver = !!this.leavers.getByConnectionId(connectionId);
34-
const isMember = !!this.getByConnectionId(connectionId);
34+
const isMember = this.members.some((m) => m.connectionId === connectionId);
3535
const memberUpdate = this.createMember(message);
3636

3737
if (action === 'leave') {
38-
this.leavers.addLeaver(memberUpdate, () => this.removeMember(connectionId));
38+
this.leavers.addLeaver(memberUpdate, () => this.onMemberOffline(memberUpdate));
3939
this.emit('leave', memberUpdate);
4040
} else if (isLeaver) {
4141
this.leavers.removeLeaver(connectionId);
4242
}
4343

44-
if (!isMember) {
44+
if (!isMember && action !== 'leave') {
4545
this.members.push(memberUpdate);
4646
this.emit('enter', memberUpdate);
47-
} else if (['enter', 'update', 'leave'].includes(action) && isMember) {
47+
} else if (['enter', 'update'].includes(action) && isMember) {
4848
const index = this.members.findIndex((m) => m.connectionId === connectionId);
4949
this.members[index] = memberUpdate;
50+
} else if (action === 'leave' && isMember) {
51+
const index = this.members.findIndex((m) => m.connectionId === connectionId);
52+
this.members.splice(index, 1);
5053
}
5154

5255
// Emit profileData updates only if they are different then the last held update.
@@ -62,11 +65,11 @@ class Members extends EventEmitter<MemberEventsMap> {
6265
}
6366

6467
getAll(): SpaceMember[] {
65-
return this.members;
68+
return this.members.concat(this.leavers.getAll().map((l) => l.member));
6669
}
6770

6871
getOthers(): SpaceMember[] {
69-
return this.members.filter((m) => m.connectionId !== this.space.connectionId);
72+
return this.getAll().filter((m) => m.connectionId !== this.space.connectionId);
7073
}
7174

7275
subscribe<K extends EventKey<MemberEventsMap>>(
@@ -110,7 +113,7 @@ class Members extends EventEmitter<MemberEventsMap> {
110113
}
111114

112115
getByConnectionId(connectionId: string): SpaceMember | undefined {
113-
return this.members.find((m) => m.connectionId === connectionId);
116+
return this.getAll().find((m) => m.connectionId === connectionId);
114117
}
115118

116119
createMember(message: PresenceMember): SpaceMember {
@@ -127,24 +130,20 @@ class Members extends EventEmitter<MemberEventsMap> {
127130
};
128131
}
129132

130-
removeMember(connectionId: string): void {
131-
const index = this.members.findIndex((m) => m.connectionId === connectionId);
132-
133-
if (index >= 0) {
134-
const member = this.members.splice(index, 1)[0];
133+
onMemberOffline(member: SpaceMember) {
134+
this.leavers.removeLeaver(member.connectionId);
135135

136-
this.emit('remove', member);
136+
this.emit('remove', member);
137137

138-
if (member.location) {
139-
this.space.locations.emit('update', {
140-
previousLocation: member.location,
141-
currentLocation: null,
142-
member: { ...member, location: null },
143-
});
144-
}
145-
146-
this.space.emit('update', { members: this.getAll() });
138+
if (member.location) {
139+
this.space.locations.emit('update', {
140+
previousLocation: member.location,
141+
currentLocation: null,
142+
member: { ...member, location: null },
143+
});
147144
}
145+
146+
this.space.emit('update', { members: this.getAll() });
148147
}
149148
}
150149

src/Space.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,17 +280,17 @@ describe('Space', () => {
280280
createPresenceEvent(space, 'leave');
281281
expect(callbackSpy).toHaveBeenNthCalledWith(3, {
282282
members: [
283-
createSpaceMember({ lastEvent: { name: 'leave', timestamp: 1 }, isConnected: false }),
284283
createSpaceMember({ clientId: '2', connectionId: '2', lastEvent: { name: 'enter', timestamp: 1 } }),
284+
createSpaceMember({ lastEvent: { name: 'leave', timestamp: 1 }, isConnected: false }),
285285
],
286286
});
287287

288288
vi.advanceTimersByTime(60_000);
289289
createPresenceEvent(space, 'enter');
290290
expect(callbackSpy).toHaveBeenNthCalledWith(4, {
291291
members: [
292-
createSpaceMember({ lastEvent: { name: 'enter', timestamp: 1 } }),
293292
createSpaceMember({ clientId: '2', connectionId: '2', lastEvent: { name: 'enter', timestamp: 1 } }),
293+
createSpaceMember({ lastEvent: { name: 'enter', timestamp: 1 } }),
294294
],
295295
});
296296

0 commit comments

Comments
 (0)