wip: refactor

This commit is contained in:
Ren Amamiya
2023-08-17 15:11:40 +07:00
parent ab61bfb2cd
commit 414dd50a5c
33 changed files with 958 additions and 648 deletions

View File

@@ -1,14 +1,13 @@
import { NDKCacheAdapter } from '@nostr-dev-kit/ndk';
import { NDKEvent, NDKSubscription } from '@nostr-dev-kit/ndk';
import { LumeStorage } from '@libs/storage/instance';
import { Store } from '@tauri-apps/plugin-store';
export default class TauriAdapter implements NDKCacheAdapter {
public store: LumeStorage;
public store: Store;
readonly locking: boolean;
constructor(db: LumeStorage) {
this.store = db;
constructor() {
this.store = new Store('.ndk_cache.dat');
this.locking = true;
}
@@ -21,34 +20,15 @@ export default class TauriAdapter implements NDKCacheAdapter {
for (const author of filter.authors) {
for (const kind of filter.kinds) {
const key = `${author}:${kind}`;
promises.concat(this.store.getALlEventByKey(key));
promises.push(this.store.get(key));
}
}
const results = await Promise.all(promises);
for (const result of results) {
if (result && result.event) {
console.log('cache hit: ', result.event);
const ndkEvent = new NDKEvent(
subscription.ndk,
JSON.parse(result.event as string)
);
subscription.eventReceived(ndkEvent, undefined, true);
}
}
}
if (filter.ids) {
for (const id of filter.ids) {
const cacheEvent = await this.store.getEventByID(id);
if (cacheEvent) {
console.log('cache hit: ', id);
const ndkEvent = new NDKEvent(
subscription.ndk,
JSON.parse(cacheEvent.event as string)
);
if (result) {
const ndkEvent = new NDKEvent(subscription.ndk, JSON.parse(result as string));
subscription.eventReceived(ndkEvent, undefined, true);
}
}
@@ -60,9 +40,13 @@ export default class TauriAdapter implements NDKCacheAdapter {
const key = `${nostrEvent.pubkey}:${nostrEvent.kind}`;
return new Promise((resolve) => {
Promise.all([
this.store.createEvent(key, event.id, event.kind, JSON.stringify(nostrEvent)),
]).then(() => resolve());
Promise.all([this.store.set(key, JSON.stringify(nostrEvent))]).then(() =>
resolve()
);
});
}
public async saveCache(): Promise<void> {
return await this.store.save();
}
}

View File

@@ -1,6 +1,6 @@
// inspire by: https://github.com/nostr-dev-kit/ndk-react/
import NDK from '@nostr-dev-kit/ndk';
import { useEffect, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import TauriAdapter from '@libs/ndk/cache';
import { useStorage } from '@libs/storage/provider';
@@ -13,6 +13,8 @@ export const NDKInstance = () => {
const [ndk, setNDK] = useState<NDK | undefined>(undefined);
const [relayUrls, setRelayUrls] = useState<string[]>([]);
const cacheAdapter = useMemo(() => new TauriAdapter(), [ndk]);
// TODO: fully support NIP-11
async function verifyRelays(relays: string[]) {
const verifiedRelays: string[] = [];
@@ -64,7 +66,6 @@ export const NDKInstance = () => {
explicitRelayUrls = await verifyRelays(FULL_RELAYS);
}
const cacheAdapter = new TauriAdapter(db);
console.log('ndk cache adapter: ', cacheAdapter);
const instance = new NDK({ explicitRelayUrls, cacheAdapter });
@@ -80,6 +81,10 @@ export const NDKInstance = () => {
useEffect(() => {
if (!ndk) initNDK();
return () => {
cacheAdapter.saveCache();
};
}, []);
return {

View File

@@ -2,7 +2,7 @@ import { BaseDirectory, removeFile } from '@tauri-apps/plugin-fs';
import Database from '@tauri-apps/plugin-sql';
import { Stronghold } from '@tauri-apps/plugin-stronghold';
import { Account, LumeEvent, Relays, Widget } from '@utils/types';
import { Account, DBEvent, Relays, Widget } from '@utils/types';
export class LumeStorage {
public db: Database;
@@ -93,6 +93,13 @@ export class LumeStorage {
}
}
public async updateLastLogin() {
return await this.db.execute(
'UPDATE accounts SET last_login_at = $1 WHERE id = $2;',
[Math.floor(Date.now() / 1000), this.account.id]
);
}
public async getWidgets() {
const result: Array<Widget> = await this.db.select(
`SELECT * FROM widgets WHERE account_id = "${this.account.id}" ORDER BY created_at DESC;`
@@ -122,35 +129,99 @@ export class LumeStorage {
}
public async createEvent(
cacheKey: string,
event_id: string,
event_kind: number,
event: string
id: string,
event: string,
author: string,
root_id: string,
reply_id: string,
created_at: number
) {
return await this.db.execute(
'INSERT OR IGNORE INTO events (cache_key, event_id, event_kind, event) VALUES ($1, $2, $3, $4);',
[cacheKey, event_id, event_kind, event]
'INSERT OR IGNORE INTO events (id, account_id, event, author, root_id, reply_id, created_at) VALUES ($1, $2, $3, $4, $5, $6, $7);',
[id, this.account.id, event, author, root_id, reply_id, created_at]
);
}
public async getALlEventByKey(cacheKey: string) {
const events: LumeEvent[] = await this.db.select(
'SELECT * FROM events WHERE cache_key = $1 ORDER BY id DESC;',
[cacheKey]
);
if (events.length < 1) return null;
return events;
}
public async getEventByID(id: string) {
const event = await this.db.select(
'SELECT * FROM events WHERE event_id = $1 ORDER BY id DESC LIMIT 1;',
const results: DBEvent[] = await this.db.select(
'SELECT * FROM events WHERE id = $1 ORDER BY id DESC LIMIT 1;',
[id]
)?.[0];
);
if (!event) return null;
return event;
if (results.length < 1) return null;
return results[0];
}
public async countTotalEvents() {
const result: Array<{ total: string }> = await this.db.select(
'SELECT COUNT(*) AS "total" FROM events;'
);
return parseInt(result[0].total);
}
public async getAllEvents(limit: number, offset: number) {
const totalEvents = await this.countTotalEvents();
const nextCursor = offset + limit;
const events: { data: DBEvent[] | null; nextCursor: number } = {
data: null,
nextCursor: 0,
};
const query: DBEvent[] = await this.db.select(
'SELECT * FROM events ORDER BY created_at DESC LIMIT $1 OFFSET $2;',
[limit, offset]
);
if (query && query.length > 0) {
events['data'] = query;
events['nextCursor'] =
Math.round(totalEvents / nextCursor) > 1 ? nextCursor : undefined;
return events;
}
return {
data: [],
nextCursor: 0,
};
}
public async getAllEventsByAuthors(authors: string[], limit: number, offset: number) {
const totalEvents = await this.countTotalEvents();
const nextCursor = offset + limit;
const authorsArr = `'${authors.join("','")}'`;
const events: { data: DBEvent[] | null; nextCursor: number } = {
data: null,
nextCursor: 0,
};
const query: DBEvent[] = await this.db.select(
'SELECT * FROM events WHERE author IN ($1) ORDER BY created_at DESC LIMIT $2 OFFSET $3;',
[authorsArr, limit, offset]
);
if (query && query.length > 0) {
events['data'] = query;
events['nextCursor'] =
Math.round(totalEvents / nextCursor) > 1 ? nextCursor : undefined;
return events;
}
return {
data: [],
nextCursor: 0,
};
}
public async isEventsEmpty() {
const results: DBEvent[] = await this.db.select(
'SELECT * FROM events ORDER BY id DESC LIMIT 1;'
);
return results.length < 1;
}
public async getExplicitRelayUrls() {
@@ -175,13 +246,6 @@ export class LumeStorage {
return await this.db.execute(`DELETE FROM relays WHERE relay = "${relay}";`);
}
public async updateLastLogin(time: number) {
return await this.db.execute(
'UPDATE settings SET value = $1 WHERE key = "last_login";',
[time]
);
}
public async removePrivkey() {
return await this.db.execute(
`UPDATE accounts SET privkey = "privkey is stored in secure storage" WHERE id = "${this.account.id}";`