feat: profile store

This commit is contained in:
Shibo Lyu 2024-10-12 01:57:29 +08:00
parent 2771381a13
commit 71a7a3c76e
2 changed files with 57 additions and 1 deletions

View file

@ -1,7 +1,7 @@
import { BlahKeyPair, BlahPublicKey, type EncodedBlahKeyPair } from '@blah-im/core/crypto'; import { BlahKeyPair, BlahPublicKey, type EncodedBlahKeyPair } from '@blah-im/core/crypto';
import { openDB, type DBSchema, type IDBPDatabase } from 'idb'; import { openDB, type DBSchema, type IDBPDatabase } from 'idb';
const IDB_NAME = 'blah-accounts'; const IDB_NAME = 'weblah-accounts';
const IDB_OBJECT_STORE_NAME = 'accounts'; const IDB_OBJECT_STORE_NAME = 'accounts';
type SavedObject = { type SavedObject = {

56
src/lib/profileStore.ts Normal file
View file

@ -0,0 +1,56 @@
import type { BlahProfile } from '@blah-im/core/identity';
import { openDB, type DBSchema, type IDBPDatabase } from 'idb';
const IDB_NAME = 'weblah-profiles';
const IDB_OBJECT_STORE_NAME = 'profiles';
const PROFILE_MAX_AGE = 1000 * 60 * 60 * 24 * 30; // 30 days
interface ProfileStoreDB extends DBSchema {
[IDB_OBJECT_STORE_NAME]: {
key: string;
value: BlahProfile & { idKeyId: string; lastUpdatedAt: Date };
indexes: { id_urls: string };
};
}
export class ProfileStore {
private db: IDBPDatabase<ProfileStoreDB>;
private constructor(db: IDBPDatabase<ProfileStoreDB>) {
this.db = db;
}
static async open(): Promise<ProfileStore> {
const db = await openDB<ProfileStoreDB>(IDB_NAME, 1, {
upgrade(db) {
if (!db.objectStoreNames.contains(IDB_OBJECT_STORE_NAME)) {
const store = db.createObjectStore(IDB_OBJECT_STORE_NAME, { keyPath: 'idKeyId' });
store.createIndex('id_urls', 'id_urls', { multiEntry: true, unique: true });
}
}
});
const store = new ProfileStore(db);
await store.removeOldProfiles();
return store;
}
async updateProfile(idKeyId: string, profile: BlahProfile): Promise<void> {
await this.db.put(IDB_OBJECT_STORE_NAME, { idKeyId, ...profile, lastUpdatedAt: new Date() });
}
async getProfile(idKeyId: string): Promise<BlahProfile | undefined> {
return await this.db.get(IDB_OBJECT_STORE_NAME, idKeyId);
}
async getProfileByIdUrl(idUrl: string): Promise<BlahProfile | undefined> {
return await this.db.getFromIndex(IDB_OBJECT_STORE_NAME, 'id_urls', idUrl);
}
async removeOldProfiles(): Promise<void> {
const now = new Date();
const cutoff = new Date(now.getTime() - PROFILE_MAX_AGE);
await this.db.delete(IDB_OBJECT_STORE_NAME, IDBKeyRange.upperBound(cutoff));
}
}