SearchStorage: make author relations work
This commit is contained in:
parent
6d80b43335
commit
d170eb6d8e
|
@ -2,7 +2,9 @@ import { Conf } from '@/config.ts';
|
||||||
import { db } from '@/db.ts';
|
import { db } from '@/db.ts';
|
||||||
import { EventsDB } from '@/storages/events-db.ts';
|
import { EventsDB } from '@/storages/events-db.ts';
|
||||||
import { Memorelay } from '@/storages/memorelay.ts';
|
import { Memorelay } from '@/storages/memorelay.ts';
|
||||||
|
import { Optimizer } from '@/storages/optimizer.ts';
|
||||||
import { SearchStore } from '@/storages/search-store.ts';
|
import { SearchStore } from '@/storages/search-store.ts';
|
||||||
|
import { reqmeister } from '@/reqmeister.ts';
|
||||||
|
|
||||||
/** SQLite database to store events this Ditto server cares about. */
|
/** SQLite database to store events this Ditto server cares about. */
|
||||||
const eventsDB = new EventsDB(db);
|
const eventsDB = new EventsDB(db);
|
||||||
|
@ -10,10 +12,17 @@ const eventsDB = new EventsDB(db);
|
||||||
/** In-memory data store for cached events. */
|
/** In-memory data store for cached events. */
|
||||||
const memorelay = new Memorelay({ max: 3000 });
|
const memorelay = new Memorelay({ max: 3000 });
|
||||||
|
|
||||||
|
/** Main Ditto storage adapter */
|
||||||
|
const optimizer = new Optimizer({
|
||||||
|
db: eventsDB,
|
||||||
|
cache: memorelay,
|
||||||
|
client: reqmeister,
|
||||||
|
});
|
||||||
|
|
||||||
/** Storage to use for remote search. */
|
/** Storage to use for remote search. */
|
||||||
const searchStore = new SearchStore({
|
const searchStore = new SearchStore({
|
||||||
relay: Conf.searchRelay,
|
relay: Conf.searchRelay,
|
||||||
fallback: eventsDB,
|
fallback: optimizer,
|
||||||
});
|
});
|
||||||
|
|
||||||
export { eventsDB, memorelay, searchStore };
|
export { eventsDB, memorelay, optimizer, searchStore };
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { Debug } from '@/deps.ts';
|
||||||
import { type DittoFilter, normalizeFilters } from '@/filter.ts';
|
import { type DittoFilter, normalizeFilters } from '@/filter.ts';
|
||||||
import { EventSet } from '@/utils/event-set.ts';
|
import { EventSet } from '@/utils/event-set.ts';
|
||||||
|
|
||||||
|
@ -10,6 +11,8 @@ interface OptimizerOpts {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Optimizer implements EventStore {
|
class Optimizer implements EventStore {
|
||||||
|
#debug = Debug('ditto:optimizer');
|
||||||
|
|
||||||
#db: EventStore;
|
#db: EventStore;
|
||||||
#cache: EventStore;
|
#cache: EventStore;
|
||||||
#client: EventStore;
|
#client: EventStore;
|
||||||
|
@ -33,6 +36,8 @@ class Optimizer implements EventStore {
|
||||||
filters: DittoFilter<K>[],
|
filters: DittoFilter<K>[],
|
||||||
opts: GetEventsOpts | undefined = {},
|
opts: GetEventsOpts | undefined = {},
|
||||||
): Promise<DittoEvent<K>[]> {
|
): Promise<DittoEvent<K>[]> {
|
||||||
|
this.#debug('REQ', JSON.stringify(filters));
|
||||||
|
|
||||||
const { limit = Infinity } = opts;
|
const { limit = Infinity } = opts;
|
||||||
filters = normalizeFilters(filters);
|
filters = normalizeFilters(filters);
|
||||||
|
|
||||||
|
@ -45,6 +50,7 @@ class Optimizer implements EventStore {
|
||||||
for (let i = 0; i < filters.length; i++) {
|
for (let i = 0; i < filters.length; i++) {
|
||||||
const filter = filters[i];
|
const filter = filters[i];
|
||||||
if (filter.ids) {
|
if (filter.ids) {
|
||||||
|
this.#debug(`Filter[${i}] is an IDs filter; querying cache...`);
|
||||||
const ids = new Set<string>(filter.ids);
|
const ids = new Set<string>(filter.ids);
|
||||||
for (const event of await this.#cache.getEvents([filter], opts)) {
|
for (const event of await this.#cache.getEvents([filter], opts)) {
|
||||||
ids.delete(event.id);
|
ids.delete(event.id);
|
||||||
|
@ -59,18 +65,27 @@ class Optimizer implements EventStore {
|
||||||
if (!filters.length) return getResults();
|
if (!filters.length) return getResults();
|
||||||
|
|
||||||
// Query the database for events.
|
// Query the database for events.
|
||||||
|
this.#debug('Querying database...');
|
||||||
for (const dbEvent of await this.#db.getEvents(filters, opts)) {
|
for (const dbEvent of await this.#db.getEvents(filters, opts)) {
|
||||||
results.add(dbEvent);
|
results.add(dbEvent);
|
||||||
if (results.size >= limit) return getResults();
|
if (results.size >= limit) return getResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We already searched the DB, so stop if this is a search filter.
|
||||||
|
if (filters.some((filter) => typeof filter.search === 'string')) {
|
||||||
|
this.#debug(`Bailing early for search filter: "${filters[0]?.search}"`);
|
||||||
|
return getResults();
|
||||||
|
}
|
||||||
|
|
||||||
// Query the cache again.
|
// Query the cache again.
|
||||||
|
this.#debug('Querying cache...');
|
||||||
for (const cacheEvent of await this.#cache.getEvents(filters, opts)) {
|
for (const cacheEvent of await this.#cache.getEvents(filters, opts)) {
|
||||||
results.add(cacheEvent);
|
results.add(cacheEvent);
|
||||||
if (results.size >= limit) return getResults();
|
if (results.size >= limit) return getResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, query the client.
|
// Finally, query the client.
|
||||||
|
this.#debug('Querying client...');
|
||||||
for (const clientEvent of await this.#client.getEvents(filters, opts)) {
|
for (const clientEvent of await this.#client.getEvents(filters, opts)) {
|
||||||
results.add(clientEvent);
|
results.add(clientEvent);
|
||||||
if (results.size >= limit) return getResults();
|
if (results.size >= limit) return getResults();
|
||||||
|
|
|
@ -57,7 +57,7 @@ class SearchStore implements EventStore {
|
||||||
const authorIds = new Set([...events].map((event) => event.pubkey));
|
const authorIds = new Set([...events].map((event) => event.pubkey));
|
||||||
const authors = await this.getEvents([{ kinds: [0], authors: [...authorIds] }], opts);
|
const authors = await this.getEvents([{ kinds: [0], authors: [...authorIds] }], opts);
|
||||||
for (const event of events) {
|
for (const event of events) {
|
||||||
event.author = authors.find((author) => author.id === event.pubkey);
|
event.author = authors.find((author) => author.pubkey === event.pubkey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue