Move client to a PoolStore storage class

This commit is contained in:
Alex Gleason 2024-01-07 15:15:20 -06:00
parent 20928cdf82
commit a10108e109
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
4 changed files with 104 additions and 78 deletions

View File

@ -1,74 +0,0 @@
import { Debug, type Event, type Filter, matchFilters } from '@/deps.ts';
import { normalizeFilters } from '@/filter.ts';
import * as pipeline from '@/pipeline.ts';
import { activeRelays, pool } from '@/pool.ts';
import { type EventStore, type GetEventsOpts, type StoreEventOpts } from '@/storages/types.ts';
import { EventSet } from '@/utils/event-set.ts';
const debug = Debug('ditto:client');
/** Get events from a NIP-01 filter. */
function getEvents<K extends number>(filters: Filter<K>[], opts: GetEventsOpts = {}): Promise<Event<K>[]> {
filters = normalizeFilters(filters);
if (opts.signal?.aborted) return Promise.resolve([]);
if (!filters.length) return Promise.resolve([]);
debug('REQ', JSON.stringify(filters));
return new Promise((resolve) => {
const results = new EventSet<Event<K>>();
const unsub = pool.subscribe(
filters,
opts.relays ?? activeRelays,
(event: Event | null) => {
if (event && matchFilters(filters, event)) {
pipeline.handleEvent(event).catch(() => {});
results.add({
id: event.id,
kind: event.kind as K,
pubkey: event.pubkey,
content: event.content,
tags: event.tags,
created_at: event.created_at,
sig: event.sig,
});
}
if (typeof opts.limit === 'number' && results.size >= opts.limit) {
unsub();
resolve([...results]);
}
},
undefined,
() => {
unsub();
resolve([...results]);
},
);
opts.signal?.addEventListener('abort', () => {
unsub();
resolve([...results]);
});
});
}
/** Publish an event to the given relays, or the entire pool. */
function storeEvent(event: Event, opts: StoreEventOpts = {}): Promise<void> {
const { relays = activeRelays } = opts;
const debug = Debug('ditto:client:publish');
debug('EVENT', event);
pool.publish(event, relays);
return Promise.resolve();
}
const client: EventStore = {
supportedNips: [1],
getEvents,
storeEvent,
countEvents: () => Promise.reject(new Error('COUNT not implemented')),
deleteEvents: () => Promise.reject(new Error('Cannot delete events from relays. Create a kind 5 event instead.')),
};
export { client };

View File

@ -1,4 +1,3 @@
import { client } from '@/client.ts';
import { Conf } from '@/config.ts'; import { Conf } from '@/config.ts';
import { addRelays } from '@/db/relays.ts'; import { addRelays } from '@/db/relays.ts';
import { deleteAttachedMedia } from '@/db/unattached-media.ts'; import { deleteAttachedMedia } from '@/db/unattached-media.ts';
@ -7,7 +6,7 @@ import { Debug, type Event } from '@/deps.ts';
import { isEphemeralKind } from '@/kinds.ts'; import { isEphemeralKind } from '@/kinds.ts';
import { isLocallyFollowed } from '@/queries.ts'; import { isLocallyFollowed } from '@/queries.ts';
import { updateStats } from '@/stats.ts'; import { updateStats } from '@/stats.ts';
import { eventsDB, memorelay, reqmeister } from '@/storages.ts'; import { client, eventsDB, memorelay, reqmeister } from '@/storages.ts';
import { Sub } from '@/subs.ts'; import { Sub } from '@/subs.ts';
import { getTagSet } from '@/tags.ts'; import { getTagSet } from '@/tags.ts';
import { type EventData } from '@/types.ts'; import { type EventData } from '@/types.ts';

View File

@ -1,13 +1,22 @@
import { client } from '@/client.ts';
import { Conf } from '@/config.ts'; import { Conf } from '@/config.ts';
import { db } from '@/db.ts'; import { db } from '@/db.ts';
import * as pipeline from '@/pipeline.ts';
import { activeRelays, pool } from '@/pool.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 { Optimizer } from '@/storages/optimizer.ts';
import { PoolStore } from '@/storages/pool-store.ts';
import { Reqmeister } from '@/storages/reqmeister.ts'; import { Reqmeister } from '@/storages/reqmeister.ts';
import { SearchStore } from '@/storages/search-store.ts'; import { SearchStore } from '@/storages/search-store.ts';
import { Time } from '@/utils/time.ts'; import { Time } from '@/utils/time.ts';
/** Relay pool storage. */
const client = new PoolStore({
pool,
relays: activeRelays,
publisher: pipeline,
});
/** 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);
@ -34,4 +43,4 @@ const searchStore = new SearchStore({
fallback: optimizer, fallback: optimizer,
}); });
export { eventsDB, memorelay, optimizer, reqmeister, searchStore }; export { client, eventsDB, memorelay, optimizer, reqmeister, searchStore };

View File

@ -0,0 +1,92 @@
import { Debug, type Event, type Filter, matchFilters, type RelayPoolWorker } from '@/deps.ts';
import { normalizeFilters } from '@/filter.ts';
import { type EventStore, type GetEventsOpts, type StoreEventOpts } from '@/storages/types.ts';
import { EventSet } from '@/utils/event-set.ts';
interface PoolStoreOpts {
pool: InstanceType<typeof RelayPoolWorker>;
relays: WebSocket['url'][];
publisher: {
handleEvent(event: Event): Promise<void>;
};
}
class PoolStore implements EventStore {
#debug = Debug('ditto:client');
#pool: InstanceType<typeof RelayPoolWorker>;
#relays: WebSocket['url'][];
#publisher: {
handleEvent(event: Event): Promise<void>;
};
supportedNips = [1];
constructor(opts: PoolStoreOpts) {
this.#pool = opts.pool;
this.#relays = opts.relays;
this.#publisher = opts.publisher;
}
storeEvent(event: Event, opts: StoreEventOpts = {}): Promise<void> {
const { relays = this.#relays } = opts;
this.#debug('EVENT', event);
this.#pool.publish(event, relays);
return Promise.resolve();
}
getEvents<K extends number>(filters: Filter<K>[], opts: GetEventsOpts = {}): Promise<Event<K>[]> {
filters = normalizeFilters(filters);
if (opts.signal?.aborted) return Promise.resolve([]);
if (!filters.length) return Promise.resolve([]);
this.#debug('REQ', JSON.stringify(filters));
return new Promise((resolve) => {
const results = new EventSet<Event<K>>();
const unsub = this.#pool.subscribe(
filters,
opts.relays ?? this.#relays,
(event: Event | null) => {
if (event && matchFilters(filters, event)) {
this.#publisher.handleEvent(event).catch(() => {});
results.add({
id: event.id,
kind: event.kind as K,
pubkey: event.pubkey,
content: event.content,
tags: event.tags,
created_at: event.created_at,
sig: event.sig,
});
}
if (typeof opts.limit === 'number' && results.size >= opts.limit) {
unsub();
resolve([...results]);
}
},
undefined,
() => {
unsub();
resolve([...results]);
},
);
opts.signal?.addEventListener('abort', () => {
unsub();
resolve([...results]);
});
});
}
countEvents() {
return Promise.reject(new Error('COUNT not implemented'));
}
deleteEvents() {
return Promise.reject(new Error('Cannot delete events from relays. Create a kind 5 event instead.'));
}
}
export { PoolStore };