Export event types from util, tweak feed interface
This commit is contained in:
@@ -14,12 +14,15 @@ const loader = new FeedLoader({
|
||||
})
|
||||
|
||||
// Define a feed using set operations
|
||||
const feed = intersection(
|
||||
union(
|
||||
dvm({kind: 5300, pubkey: '19b78ccfa7c5e31e6bacbb3f2a1703f64b62017702e584440bf29a7e16263e8c'}),
|
||||
list("10003:19ba654f26afd4930fd3d51baf4e26f1413b7aeec7190cd6c0cdf4d2f14cec6b:"),
|
||||
const feed = intersectionFeed(
|
||||
unionFeed(
|
||||
dvmFeed({
|
||||
kind: 5300,
|
||||
pubkey: '19b78ccfa7c5e31e6bacbb3f2a1703f64b62017702e584440bf29a7e16263e8c',
|
||||
}),
|
||||
listFeed("10003:19ba654f26afd4930fd3d51baf4e26f1413b7aeec7190cd6c0cdf4d2f14cec6b:"),
|
||||
)
|
||||
filter({
|
||||
filterFeed({
|
||||
min_wot: 0.1,
|
||||
scopes: ["global"],
|
||||
}),
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import {inc, uniq, now, isNil} from '@coracle.social/lib'
|
||||
import type {Rumor, Filter} from '@coracle.social/util'
|
||||
import {Tags, getIdFilters, mergeFilters} from '@coracle.social/util'
|
||||
import type {RequestItem, DVMItem, Scope, Feed, DynamicFilter, FeedContext} from './core'
|
||||
import type {RequestItem, DVMItem, Scope, Feed, DynamicFilter, FeedOptions} from './core'
|
||||
import {FeedType} from './core'
|
||||
|
||||
export class FeedCompiler<E extends Rumor> {
|
||||
constructor(readonly context: FeedContext<E>) {}
|
||||
constructor(readonly options: FeedOptions<E>) {}
|
||||
|
||||
walk([type, ...feed]: Feed, visit: (feed: Feed) => void) {
|
||||
visit([type, ...feed] as Feed)
|
||||
@@ -88,7 +88,7 @@ export class FeedCompiler<E extends Rumor> {
|
||||
async _compileLists(addresses: string[]): Promise<RequestItem> {
|
||||
const events: E[] = []
|
||||
|
||||
await this.context.request({
|
||||
await this.options.request({
|
||||
relays: [],
|
||||
filters: getIdFilters(addresses),
|
||||
onEvent: events.push,
|
||||
@@ -103,7 +103,7 @@ export class FeedCompiler<E extends Rumor> {
|
||||
async _compileLols(addresses: string[]): Promise<RequestItem> {
|
||||
const events: E[] = []
|
||||
|
||||
await this.context.request({
|
||||
await this.options.request({
|
||||
relays: [],
|
||||
filters: getIdFilters(addresses),
|
||||
onEvent: events.push,
|
||||
@@ -117,7 +117,7 @@ export class FeedCompiler<E extends Rumor> {
|
||||
|
||||
await Promise.all(
|
||||
requests.map(request =>
|
||||
this.context.requestDvm({
|
||||
this.options.requestDvm({
|
||||
tags: [],
|
||||
...request,
|
||||
onEvent: events.push,
|
||||
@@ -135,11 +135,11 @@ export class FeedCompiler<E extends Rumor> {
|
||||
|
||||
_compileFilter({scopes, min_wot, max_wot, until_ago, since_ago, ...filter}: DynamicFilter) {
|
||||
if (scopes && !filter.authors) {
|
||||
filter.authors = scopes.flatMap((scope: Scope) => this.context.getPubkeysForScope(scope))
|
||||
filter.authors = scopes.flatMap((scope: Scope) => this.options.getPubkeysForScope(scope))
|
||||
}
|
||||
|
||||
if ((!isNil(min_wot) || !isNil(max_wot))) {
|
||||
const authors = this.context.getPubkeysForWotRange(min_wot || 0, max_wot || 1)
|
||||
const authors = this.options.getPubkeysForWotRange(min_wot || 0, max_wot || 1)
|
||||
|
||||
if (filter.authors) {
|
||||
const authorsSet = new Set(authors)
|
||||
|
||||
+10
-10
@@ -52,15 +52,15 @@ export type Feed =
|
||||
LOLFeed |
|
||||
DVMFeed
|
||||
|
||||
export const usingRelays = (relays: string[], ...feeds: Feed[]) => [FeedType.Relay, relays, ...feeds] as Feed
|
||||
export const difference = (...feeds: Feed[]) => [FeedType.Difference, ...feeds] as Feed
|
||||
export const intersection = (...feeds: Feed[]) => [FeedType.Intersection, ...feeds] as Feed
|
||||
export const symmetricDifference = (...feeds: Feed[]) => [FeedType.SymmetricDifference, ...feeds] as Feed
|
||||
export const union = (...feeds: Feed[]) => [FeedType.Union, ...feeds] as Feed
|
||||
export const filter = (...filters: DynamicFilter[]) => [FeedType.Filter, ...filters] as Feed
|
||||
export const list = (...addresses: string[]) => [FeedType.List, ...addresses] as Feed
|
||||
export const lol = (...addresses: string[]) => [FeedType.LOL, ...addresses] as Feed
|
||||
export const dvm = (...requests: DVMItem[]) => [FeedType.DVM, ...requests] as Feed
|
||||
export const relayFeed = (relays: string[], ...feeds: Feed[]) => [FeedType.Relay, relays, ...feeds] as Feed
|
||||
export const differenceFeed = (...feeds: Feed[]) => [FeedType.Difference, ...feeds] as Feed
|
||||
export const intersectionFeed = (...feeds: Feed[]) => [FeedType.Intersection, ...feeds] as Feed
|
||||
export const symmetricDifferenceFeed = (...feeds: Feed[]) => [FeedType.SymmetricDifference, ...feeds] as Feed
|
||||
export const unionFeed = (...feeds: Feed[]) => [FeedType.Union, ...feeds] as Feed
|
||||
export const filterFeed = (...filters: DynamicFilter[]) => [FeedType.Filter, ...filters] as Feed
|
||||
export const listFeed = (...addresses: string[]) => [FeedType.List, ...addresses] as Feed
|
||||
export const lolFeed = (...addresses: string[]) => [FeedType.LOL, ...addresses] as Feed
|
||||
export const dvmFeed = (...requests: DVMItem[]) => [FeedType.DVM, ...requests] as Feed
|
||||
|
||||
export type RequestItem = {
|
||||
relays: string[]
|
||||
@@ -80,7 +80,7 @@ export type DVMOpts<E> = DVMItem & {
|
||||
onEvent: (event: E) => void
|
||||
}
|
||||
|
||||
export type FeedContext<E> = {
|
||||
export type FeedOptions<E> = {
|
||||
request: (opts: RequestOpts<E>) => Promise<void>
|
||||
requestDvm: (opts: DVMOpts<E>) => Promise<void>
|
||||
getPubkeysForScope: (scope: Scope) => string[]
|
||||
|
||||
+25
-23
@@ -1,13 +1,13 @@
|
||||
import {inc, max, min, now, isNil} from '@coracle.social/lib'
|
||||
import type {Rumor, Filter} from '@coracle.social/util'
|
||||
import {Tags, EPOCH, getIdFilters, guessFilterDelta, mergeFilters} from '@coracle.social/util'
|
||||
import type {Scope, Feed, DynamicFilter, RequestOpts, RequestItem, FeedContext} from './core'
|
||||
import type {Scope, Feed, DynamicFilter, RequestOpts, RequestItem, FeedOptions} from './core'
|
||||
import {FeedType} from './core'
|
||||
import {FeedCompiler} from './compiler'
|
||||
|
||||
export type LoadOpts<E> = {
|
||||
onEvent: (event: E) => void
|
||||
onExhausted: () => void
|
||||
onEvent?: (event: E) => void
|
||||
onExhausted?: () => void
|
||||
}
|
||||
|
||||
export type Loader = (limit: number) => Promise<void>
|
||||
@@ -15,8 +15,8 @@ export type Loader = (limit: number) => Promise<void>
|
||||
export class FeedLoader<E extends Rumor> {
|
||||
compiler: FeedCompiler<E>
|
||||
|
||||
constructor(readonly context: FeedContext<E>) {
|
||||
this.compiler = new FeedCompiler(context)
|
||||
constructor(readonly options: FeedOptions<E>) {
|
||||
this.compiler = new FeedCompiler(options)
|
||||
}
|
||||
|
||||
async getLoader([type, ...feed]: Feed, loadOpts: LoadOpts<E>) {
|
||||
@@ -63,15 +63,17 @@ export class FeedLoader<E extends Rumor> {
|
||||
|
||||
let count = 0
|
||||
|
||||
await this.context.request({
|
||||
relays,
|
||||
filters: requestFilters,
|
||||
onEvent: (event: E) => {
|
||||
count += 1
|
||||
since = Math.min(since, event.created_at)
|
||||
onEvent(event)
|
||||
},
|
||||
})
|
||||
if (requestFilters.length > 0) {
|
||||
await this.options.request({
|
||||
relays,
|
||||
filters: requestFilters,
|
||||
onEvent: (event: E) => {
|
||||
count += 1
|
||||
until = Math.min(until, event.created_at)
|
||||
onEvent?.(event)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Relays can't be relied upon to return events in descending order, do exponential
|
||||
// windowing to ensure we get the most recent stuff on first load, but eventually find it all
|
||||
@@ -82,7 +84,7 @@ export class FeedLoader<E extends Rumor> {
|
||||
since = Math.max(minSince, since - delta)
|
||||
|
||||
if (since === minSince) {
|
||||
onExhausted()
|
||||
onExhausted?.()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,13 +123,13 @@ export class FeedLoader<E extends Rumor> {
|
||||
|
||||
for (const event of events.splice(0)) {
|
||||
if (!skip.has(event.id) && !seen.has(event.id)) {
|
||||
onEvent(event)
|
||||
onEvent?.(event)
|
||||
seen.add(event.id)
|
||||
}
|
||||
}
|
||||
|
||||
if (exhausted.size === loaders.length) {
|
||||
onExhausted()
|
||||
onExhausted?.()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,13 +165,13 @@ export class FeedLoader<E extends Rumor> {
|
||||
|
||||
for (const event of events.splice(0)) {
|
||||
if (counts.get(event.id) === loaders.length && !seen.has(event.id)) {
|
||||
onEvent(event)
|
||||
onEvent?.(event)
|
||||
seen.add(event.id)
|
||||
}
|
||||
}
|
||||
|
||||
if (exhausted.size === loaders.length) {
|
||||
onExhausted()
|
||||
onExhausted?.()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -205,13 +207,13 @@ export class FeedLoader<E extends Rumor> {
|
||||
|
||||
for (const event of events.values()) {
|
||||
if (counts.get(event.id) === 1 && !seen.has(event.id)) {
|
||||
onEvent(event)
|
||||
onEvent?.(event)
|
||||
seen.add(event.id)
|
||||
}
|
||||
}
|
||||
|
||||
if (exhausted.size === loaders.length) {
|
||||
onExhausted()
|
||||
onExhausted?.()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,7 +228,7 @@ export class FeedLoader<E extends Rumor> {
|
||||
onExhausted: () => exhausted.add(i),
|
||||
onEvent: (event: E) => {
|
||||
if (!seen.has(event.id)) {
|
||||
onEvent(event)
|
||||
onEvent?.(event)
|
||||
seen.add(event.id)
|
||||
}
|
||||
},
|
||||
@@ -246,7 +248,7 @@ export class FeedLoader<E extends Rumor> {
|
||||
)
|
||||
|
||||
if (exhausted.size === loaders.length) {
|
||||
onExhausted()
|
||||
onExhausted?.()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,12 +166,6 @@ export const mergeSubscriptions = (subs: Subscription[]) => {
|
||||
}
|
||||
}
|
||||
|
||||
// console.log(
|
||||
// `Starting ${mergedSubscriptions.length} subscriptions on ${uniq(mergedSubscriptions.flatMap(s => s.request.relays)).length} relays`,
|
||||
// uniq(mergedSubscriptions.flatMap(s => s.request.relays)),
|
||||
// ...mergeFilters(mergedSubscriptions.flatMap(s => s.request.filters)),
|
||||
// )
|
||||
|
||||
return mergedSubscriptions
|
||||
}
|
||||
|
||||
@@ -265,12 +259,6 @@ export const subscribe = (request: SubscribeRequest) => {
|
||||
}
|
||||
|
||||
if (request.immediate) {
|
||||
// console.log(
|
||||
// `Starting 1 subscriptions on ${request.relays.length} relays`,
|
||||
// request.relays,
|
||||
// ...mergeFilters(request.filters)
|
||||
// )
|
||||
|
||||
executeSubscription(subscription)
|
||||
} else {
|
||||
executeSubscriptionBatched(subscription)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type {Event, EventTemplate, UnsignedEvent} from 'nostr-tools'
|
||||
export type {Event, EventTemplate, UnsignedEvent} from 'nostr-tools'
|
||||
import {verifyEvent, getEventHash} from 'nostr-tools'
|
||||
import {cached, now} from '@coracle.social/lib'
|
||||
import {Tags} from './Tags'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@coracle.social/util",
|
||||
"version": "0.0.7",
|
||||
"version": "0.0.8",
|
||||
"author": "hodlbod",
|
||||
"license": "MIT",
|
||||
"description": "A collection of utilities.",
|
||||
|
||||
Reference in New Issue
Block a user