85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
import { by_character, by_lurid } from 'jsr:@andyburke/fsdb/organizers';
|
|
import { FSDB_COLLECTION } from 'jsr:@andyburke/fsdb';
|
|
import { FSDB_INDEXER_SYMLINKS } from 'jsr:@andyburke/fsdb/indexers';
|
|
|
|
/**
|
|
* @typedef {object} TIMESTAMPS
|
|
* @property {string} created when the event was created
|
|
* @property {string} updated when the event was last updated
|
|
*/
|
|
|
|
/**
|
|
* Event
|
|
*
|
|
* @property {string} id - lurid
|
|
* @property {string} creator_id - id of the source user
|
|
* @property {string} room_id - id of the target room
|
|
* @property {string} type - event type
|
|
* @property {string[]} [tags] - optional event tags
|
|
* @property {Record<string,any>} [data] - optional data payload of the event
|
|
* @property {TIMESTAMPS} timestamps - timestamps that will be set by the server
|
|
*/
|
|
export type EVENT = {
|
|
id: string;
|
|
creator_id: string;
|
|
type: string;
|
|
tags?: string[];
|
|
data?: Record<string, any>;
|
|
timestamps: {
|
|
created: string;
|
|
updated: string;
|
|
};
|
|
};
|
|
|
|
type ROOM_EVENT_CACHE_ENTRY = {
|
|
collection: FSDB_COLLECTION<EVENT>;
|
|
eviction_timeout: number;
|
|
};
|
|
|
|
const ROOM_EVENTS: Record<string, ROOM_EVENT_CACHE_ENTRY> = {};
|
|
export function get_events_collection_for_room(room_id: string): FSDB_COLLECTION<EVENT> {
|
|
ROOM_EVENTS[room_id] = ROOM_EVENTS[room_id] ?? {
|
|
collection: new FSDB_COLLECTION<EVENT>({
|
|
name: `rooms/${room_id.slice(0, 14)}/${room_id.slice(0, 34)}/${room_id}/events`,
|
|
id_field: 'id',
|
|
organize: by_lurid,
|
|
indexers: {
|
|
creator_id: new FSDB_INDEXER_SYMLINKS<EVENT>({
|
|
name: 'creator_id',
|
|
field: 'creator_id',
|
|
to_many: true,
|
|
organize: by_lurid
|
|
}),
|
|
|
|
tags: new FSDB_INDEXER_SYMLINKS<EVENT>({
|
|
name: 'tags',
|
|
get_values_to_index: (event: EVENT): string[] => {
|
|
return (event.tags ?? []).map((tag: string) => tag.toLowerCase());
|
|
},
|
|
to_many: true,
|
|
organize: by_character
|
|
})
|
|
}
|
|
}),
|
|
eviction_timeout: 0
|
|
};
|
|
|
|
if (ROOM_EVENTS[room_id].eviction_timeout) {
|
|
clearTimeout(ROOM_EVENTS[room_id].eviction_timeout);
|
|
}
|
|
|
|
ROOM_EVENTS[room_id].eviction_timeout = setTimeout(() => {
|
|
delete ROOM_EVENTS[room_id];
|
|
}, 60_000 * 5);
|
|
|
|
return ROOM_EVENTS[room_id].collection;
|
|
}
|
|
|
|
export function clear_room_events_cache() {
|
|
for (const [room_id, cached] of Object.entries(ROOM_EVENTS)) {
|
|
if (cached.eviction_timeout) {
|
|
clearTimeout(cached.eviction_timeout);
|
|
}
|
|
delete ROOM_EVENTS[room_id];
|
|
}
|
|
}
|