mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
relay: add support for NIP-45 COUNT
This commit is contained in:
parent
fc1ed59002
commit
d01dbcbfee
2 changed files with 19 additions and 5 deletions
|
|
@ -3,6 +3,7 @@ import * as pipeline from '@/pipeline.ts';
|
||||||
import { jsonSchema } from '@/schema.ts';
|
import { jsonSchema } from '@/schema.ts';
|
||||||
import {
|
import {
|
||||||
type ClientCLOSE,
|
type ClientCLOSE,
|
||||||
|
type ClientCOUNT,
|
||||||
type ClientEVENT,
|
type ClientEVENT,
|
||||||
type ClientMsg,
|
type ClientMsg,
|
||||||
clientMsgSchema,
|
clientMsgSchema,
|
||||||
|
|
@ -13,7 +14,7 @@ import { Sub } from '@/subs.ts';
|
||||||
import type { AppController } from '@/app.ts';
|
import type { AppController } from '@/app.ts';
|
||||||
import type { Event, Filter } from '@/deps.ts';
|
import type { Event, Filter } from '@/deps.ts';
|
||||||
|
|
||||||
/** Limit of events returned per-filter. */
|
/** Limit of initial events returned for a subscription. */
|
||||||
const FILTER_LIMIT = 100;
|
const FILTER_LIMIT = 100;
|
||||||
|
|
||||||
/** NIP-01 relay to client message. */
|
/** NIP-01 relay to client message. */
|
||||||
|
|
@ -21,7 +22,8 @@ type RelayMsg =
|
||||||
| ['EVENT', string, Event]
|
| ['EVENT', string, Event]
|
||||||
| ['NOTICE', string]
|
| ['NOTICE', string]
|
||||||
| ['EOSE', string]
|
| ['EOSE', string]
|
||||||
| ['OK', string, boolean, string];
|
| ['OK', string, boolean, string]
|
||||||
|
| ['COUNT', string, { count: number; approximate?: boolean }];
|
||||||
|
|
||||||
/** Set up the Websocket connection. */
|
/** Set up the Websocket connection. */
|
||||||
function connectStream(socket: WebSocket) {
|
function connectStream(socket: WebSocket) {
|
||||||
|
|
@ -50,6 +52,9 @@ function connectStream(socket: WebSocket) {
|
||||||
case 'CLOSE':
|
case 'CLOSE':
|
||||||
handleClose(msg);
|
handleClose(msg);
|
||||||
return;
|
return;
|
||||||
|
case 'COUNT':
|
||||||
|
handleCount(msg);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,7 +62,7 @@ function connectStream(socket: WebSocket) {
|
||||||
async function handleReq([_, subId, ...rest]: ClientREQ): Promise<void> {
|
async function handleReq([_, subId, ...rest]: ClientREQ): Promise<void> {
|
||||||
const filters = prepareFilters(rest);
|
const filters = prepareFilters(rest);
|
||||||
|
|
||||||
for (const event of await eventsDB.getFilters(filters)) {
|
for (const event of await eventsDB.getFilters(filters, { limit: FILTER_LIMIT })) {
|
||||||
send(['EVENT', subId, event]);
|
send(['EVENT', subId, event]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,6 +93,12 @@ function connectStream(socket: WebSocket) {
|
||||||
Sub.unsub(socket, subId);
|
Sub.unsub(socket, subId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Handle COUNT. Return the number of events matching the filters. */
|
||||||
|
async function handleCount([_, subId, ...rest]: ClientCOUNT): Promise<void> {
|
||||||
|
const count = await eventsDB.countFilters(prepareFilters(rest));
|
||||||
|
send(['COUNT', subId, { count, approximate: false }]);
|
||||||
|
}
|
||||||
|
|
||||||
/** Send a message back to the client. */
|
/** Send a message back to the client. */
|
||||||
function send(msg: RelayMsg): void {
|
function send(msg: RelayMsg): void {
|
||||||
if (socket.readyState === WebSocket.OPEN) {
|
if (socket.readyState === WebSocket.OPEN) {
|
||||||
|
|
@ -100,8 +111,6 @@ function connectStream(socket: WebSocket) {
|
||||||
function prepareFilters(filters: ClientREQ[2][]): Filter[] {
|
function prepareFilters(filters: ClientREQ[2][]): Filter[] {
|
||||||
return filters.map((filter) => ({
|
return filters.map((filter) => ({
|
||||||
...filter,
|
...filter,
|
||||||
// Limit the number of events returned per-filter.
|
|
||||||
limit: Math.min(filter.limit || FILTER_LIMIT, FILTER_LIMIT),
|
|
||||||
// Return only local events unless the query is already narrow.
|
// Return only local events unless the query is already narrow.
|
||||||
local: !filter.ids?.length && !filter.authors?.length,
|
local: !filter.ids?.length && !filter.authors?.length,
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,14 @@ const filterSchema = z.object({
|
||||||
const clientReqSchema = z.tuple([z.literal('REQ'), z.string().min(1)]).rest(filterSchema);
|
const clientReqSchema = z.tuple([z.literal('REQ'), z.string().min(1)]).rest(filterSchema);
|
||||||
const clientEventSchema = z.tuple([z.literal('EVENT'), signedEventSchema]);
|
const clientEventSchema = z.tuple([z.literal('EVENT'), signedEventSchema]);
|
||||||
const clientCloseSchema = z.tuple([z.literal('CLOSE'), z.string().min(1)]);
|
const clientCloseSchema = z.tuple([z.literal('CLOSE'), z.string().min(1)]);
|
||||||
|
const clientCountSchema = z.tuple([z.literal('COUNT'), z.string().min(1)]).rest(filterSchema);
|
||||||
|
|
||||||
/** Client message to a Nostr relay. */
|
/** Client message to a Nostr relay. */
|
||||||
const clientMsgSchema = z.union([
|
const clientMsgSchema = z.union([
|
||||||
clientReqSchema,
|
clientReqSchema,
|
||||||
clientEventSchema,
|
clientEventSchema,
|
||||||
clientCloseSchema,
|
clientCloseSchema,
|
||||||
|
clientCountSchema,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/** REQ message from client to relay. */
|
/** REQ message from client to relay. */
|
||||||
|
|
@ -53,6 +55,8 @@ type ClientREQ = z.infer<typeof clientReqSchema>;
|
||||||
type ClientEVENT = z.infer<typeof clientEventSchema>;
|
type ClientEVENT = z.infer<typeof clientEventSchema>;
|
||||||
/** CLOSE message from client to relay. */
|
/** CLOSE message from client to relay. */
|
||||||
type ClientCLOSE = z.infer<typeof clientCloseSchema>;
|
type ClientCLOSE = z.infer<typeof clientCloseSchema>;
|
||||||
|
/** COUNT message from client to relay. */
|
||||||
|
type ClientCOUNT = z.infer<typeof clientCountSchema>;
|
||||||
/** Client message to a Nostr relay. */
|
/** Client message to a Nostr relay. */
|
||||||
type ClientMsg = z.infer<typeof clientMsgSchema>;
|
type ClientMsg = z.infer<typeof clientMsgSchema>;
|
||||||
|
|
||||||
|
|
@ -88,6 +92,7 @@ const connectResponseSchema = z.object({
|
||||||
|
|
||||||
export {
|
export {
|
||||||
type ClientCLOSE,
|
type ClientCLOSE,
|
||||||
|
type ClientCOUNT,
|
||||||
type ClientEVENT,
|
type ClientEVENT,
|
||||||
type ClientMsg,
|
type ClientMsg,
|
||||||
clientMsgSchema,
|
clientMsgSchema,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue