regorganizing and attempting to allow rehydration

This commit is contained in:
Jaron
2024-11-15 13:49:33 -06:00
parent 5b1fa15e66
commit f3b1546d54
17 changed files with 381 additions and 271 deletions
+71
View File
@@ -0,0 +1,71 @@
import { fromDiscord } from "../../types/common";
import type { Context } from "../../types/context";
import type { API } from "../api";
import type { Processor } from "../processor";
export class ObjectCache<T, K extends T> {
cache = new Map<string, K>();
requests = new Map<string, Promise<K>>();
readonly type: string;
constructor(protected api: API, processor: Processor, type: string, private readonly factory: { [fromDiscord]: (data: any) => K } & (new (data: T) => T), events: string[]) {
this.type = type;
processor.events.register(events, async (_context: Context, e: Record<string, any>) => {
this.cache.set(e.id, factory[fromDiscord](e));
});
}
set(object_id: string, object: K): void {
this.cache.set(object_id, object);
}
// update(object_id: string, object: Partial<T>): void {
// const existing = this.cache.get(object_id);
// if (exists(existing)) {
// // TODO: Idk wtf happens if this is called on two classes
// this.cache.set(object_id, { ...existing, ...object });
// } else {
// this.cache.set(object_id, object as T);
// }
// }
async fetch(object_id: string, ..._args: any[]): Promise<K> {
if (this.requests.has(object_id)) {
return this.requests.get(object_id)!;
// } else if (this.cache.has(object_id)) {
// return Promise.resolve(this.cache.get(object_id)!);
} else {
// Dispatch the request
const req = this.api.get(`/${this.type}/${object_id}`).then((data) => {
// Create the object
const object = this.factory[fromDiscord](data);
// Save the object
this.cache.set(object_id, object);
// Return the object
return object;
});
// Save the request
this.requests.set(object_id, req);
// Remove the request from the cache if it succeeds
req.then(() => this.requests.delete(object_id));
// Remove the request from the cache if it fails
req.catch(() => this.requests.delete(object_id));
// Return the request
return req;
}
}
async get(object_id: string, ..._args: any[]): Promise<K> {
if (this.cache.has(object_id)) {
return await Promise.resolve(this.cache.get(object_id)!);
} else {
return this.fetch(object_id);
}
}
list(): Map<string, Promise<T> | T> {
return this.cache;
}
}
+10
View File
@@ -0,0 +1,10 @@
import { Guild } from "../../types/guild";
import type { API } from "../api";
import type { Processor } from "../processor";
import { ObjectCache } from "./cache";
export class Guilds extends ObjectCache<Guild, Guild> {
constructor (api: API, processor: Processor) {
super(api, processor, 'guilds', Guild, ['GUILD_CREATE', 'GUILD_UPDATE']);
}
}
+42
View File
@@ -0,0 +1,42 @@
import { fromDiscord } from "../../types/common";
import { Message, type MessagePayload } from "../../types/message";
import type { API } from "../api";
import type { Client } from "../client";
import type { Processor } from "../processor";
import { ObjectCache } from "./cache";
export class Messages extends ObjectCache<Message, MessagePayload> {
constructor (protected client: Client, api: API, processor: Processor) {
super(api, processor, 'message', Message, ['MESSAGE_CREATE', 'MESSAGE_UPDATE']);
}
async fetch(channel_id: string, message_id: string): Promise<MessagePayload> {
if (this.requests.has(message_id)) {
return this.requests.get(message_id)!;
} else {
// Dispatch the request
const req = this.api.get(`/channels/${channel_id}/messages/${message_id}`).then((data) => {
const message = Message[fromDiscord](data);
this.cache.set(message_id, message);
return message;
});
// Save the request
this.requests.set(message_id, req);
// Remove the request from the cache if it succeeds
req.then(() => this.requests.delete(message_id));
// Remove the request from the cache if it fails
req.catch(() => this.requests.delete(message_id));
// Return the request
return req;
}
}
async get(channel_id: string, message_id: string): Promise<MessagePayload> {
if (this.cache.has(message_id)) {
return await Promise.resolve(this.cache.get(message_id)!);
} else {
return this.fetch(channel_id, message_id);
}
}
}
+11
View File
@@ -0,0 +1,11 @@
import { User } from "../../types/user";
import type { API } from "../api";
import type { Processor } from "../processor";
import { ObjectCache } from "./cache";
export class Users extends ObjectCache<User, User> {
constructor (api: API, processor: Processor) {
super(api, processor, 'users', User, []);
}
}