Skip to content

Commit ac9c3eb

Browse files
committed
Refactor RoomResource to improve skill event handling and caching logic
1 parent 81c4b3d commit ac9c3eb

File tree

1 file changed

+65
-59
lines changed

1 file changed

+65
-59
lines changed

packages/host/app/resources/room.ts

+65-59
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,6 @@ import type CardService from '../services/card-service';
4747
import type CommandService from '../services/command-service';
4848
import type MatrixService from '../services/matrix-service';
4949

50-
interface SkillId {
51-
skillCardId: string;
52-
skillEventId: string;
53-
isActive: boolean;
54-
}
55-
5650
interface Args {
5751
named: {
5852
roomId: string | undefined;
@@ -62,6 +56,8 @@ interface Args {
6256

6357
export class RoomResource extends Resource<Args> {
6458
private _messageCache: TrackedMap<string, Message> = new TrackedMap();
59+
private _skillEventIdToCardIdCache: TrackedMap<string, string> =
60+
new TrackedMap();
6561
private _skillCardsCache: TrackedMap<string, SkillCard> = new TrackedMap();
6662
private _nameEventsCache: TrackedMap<string, RoomNameEvent> =
6763
new TrackedMap();
@@ -113,7 +109,11 @@ export class RoomResource extends Resource<Args> {
113109
await this.loadRoomMemberEvent(roomId, event);
114110
break;
115111
case 'm.room.message':
116-
await this.loadRoomMessage({ roomId, event, index });
112+
if (this.isCardFragmentEvent(event)) {
113+
await this.loadCardFragment(event);
114+
} else {
115+
await this.loadRoomMessage({ roomId, event, index });
116+
}
117117
break;
118118
case APP_BOXEL_COMMAND_RESULT_EVENT_TYPE:
119119
this.updateMessageCommandResult({ roomId, event, index });
@@ -188,60 +188,42 @@ export class RoomResource extends Resource<Args> {
188188
}
189189

190190
@cached
191-
get skillIds(): SkillId[] {
191+
get allSkillEventIds(): Set<string> {
192192
let skillsConfig = this.matrixRoom?.skillsConfig;
193193
if (!skillsConfig) {
194-
return [];
194+
return new Set();
195195
}
196-
let result: SkillId[] = [];
197-
for (let eventId of [
196+
return new Set([
198197
...skillsConfig.enabledEventIds,
199198
...skillsConfig.disabledEventIds,
200-
]) {
201-
let cardDoc;
202-
try {
203-
cardDoc = this.serializedCardFromFragments(eventId);
204-
} catch {
205-
// the skill card fragments might not be loaded yet
199+
]);
200+
}
201+
202+
@cached
203+
get skills(): Skill[] {
204+
let skillsConfig = this.matrixRoom?.skillsConfig;
205+
if (!skillsConfig) {
206+
return [];
207+
}
208+
let result: Skill[] = [];
209+
for (let skillEventId of this.allSkillEventIds) {
210+
let cardId = this._skillEventIdToCardIdCache.get(skillEventId);
211+
if (!cardId) {
206212
continue;
207213
}
208-
if (!cardDoc.data.id) {
214+
let skillCard = this._skillCardsCache.get(cardId);
215+
if (!skillCard) {
209216
continue;
210217
}
211-
let cardId = cardDoc.data.id;
212-
if (!this._skillCardsCache.has(cardId)) {
213-
this.cardService
214-
.createFromSerialized(cardDoc.data, cardDoc)
215-
.then((skillsCard) => {
216-
this._skillCardsCache.set(cardId, skillsCard as SkillCard);
217-
});
218-
}
219218
result.push({
220-
skillCardId: cardDoc.data.id,
221-
skillEventId: eventId,
222-
isActive: skillsConfig.enabledEventIds.includes(eventId),
219+
card: skillCard,
220+
skillEventId,
221+
isActive: skillsConfig.enabledEventIds.includes(skillEventId),
223222
});
224223
}
225224
return result;
226225
}
227226

228-
@cached
229-
get skills(): Skill[] {
230-
return this.skillIds
231-
.map(({ skillCardId, skillEventId, isActive }) => {
232-
let card = this._skillCardsCache.get(skillCardId);
233-
if (card) {
234-
return {
235-
card,
236-
skillEventId,
237-
isActive,
238-
};
239-
}
240-
return null;
241-
})
242-
.filter(Boolean) as Skill[];
243-
}
244-
245227
@cached
246228
get created() {
247229
if (this._createEvent) {
@@ -320,24 +302,48 @@ export class RoomResource extends Resource<Args> {
320302
});
321303
}
322304

323-
private loadRoomMessage({
324-
roomId,
325-
event,
326-
index,
327-
}: {
328-
roomId: string;
329-
event: MessageEvent | CommandEvent | CardMessageEvent;
330-
index: number;
331-
}) {
332-
if (event.content.msgtype === APP_BOXEL_CARDFRAGMENT_MSGTYPE) {
333-
this._fragmentCache.set(event.event_id, event.content);
305+
private isCardFragmentEvent(
306+
event: MessageEvent | CommandEvent | CardMessageEvent,
307+
): event is CardMessageEvent & {
308+
content: { msgtype: typeof APP_BOXEL_CARDFRAGMENT_MSGTYPE };
309+
} {
310+
return event.content.msgtype === APP_BOXEL_CARDFRAGMENT_MSGTYPE;
311+
}
312+
313+
private async loadSkillCardIntoCache(eventId: string) {
314+
let cardDoc = this.serializedCardFromFragments(eventId);
315+
if (!cardDoc.data.id) {
316+
console.warn(
317+
`No card id found for skill event id ${eventId}, this should not happen, this can happen if you add a skill card to a room without saving it, and without giving it an ID`,
318+
);
334319
return;
335320
}
321+
let cardId = cardDoc.data.id;
322+
let skillCard = (await this.cardService.createFromSerialized(
323+
cardDoc.data,
324+
cardDoc,
325+
)) as SkillCard;
326+
this._skillCardsCache.set(cardId, skillCard);
327+
this._skillEventIdToCardIdCache.set(eventId, cardId);
328+
}
336329

337-
this.upsertMessage({ roomId, event, index });
330+
private async loadCardFragment(
331+
event: CardMessageEvent & {
332+
content: { msgtype: typeof APP_BOXEL_CARDFRAGMENT_MSGTYPE };
333+
},
334+
) {
335+
let eventId = event.event_id;
336+
this._fragmentCache.set(eventId, event.content);
337+
if (
338+
!this.allSkillEventIds.has(eventId) ||
339+
this._skillEventIdToCardIdCache.has(eventId)
340+
) {
341+
return;
342+
}
343+
await this.loadSkillCardIntoCache(eventId);
338344
}
339345

340-
private upsertMessage({
346+
private loadRoomMessage({
341347
roomId,
342348
event,
343349
index,

0 commit comments

Comments
 (0)