Add default feed loader to app
This commit is contained in:
Generated
+2
@@ -3639,6 +3639,8 @@
|
||||
"version": "0.0.11",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@welshman/dvm": "~0.0.9",
|
||||
"@welshman/feeds": "~0.0.19",
|
||||
"@welshman/lib": "~0.0.19",
|
||||
"@welshman/net": "~0.0.24",
|
||||
"@welshman/signer": "~0.0.7",
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@welshman/lib": "~0.0.19",
|
||||
"@welshman/feeds": "~0.0.19",
|
||||
"@welshman/dvm": "~0.0.9",
|
||||
"@welshman/net": "~0.0.24",
|
||||
"@welshman/signer": "~0.0.7",
|
||||
"@welshman/store": "~0.0.9",
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
import {ctx, now} from '@welshman/lib'
|
||||
import {createEvent, getPubkeyTagValues} from '@welshman/util'
|
||||
import {FeedLoader, Scope} from '@welshman/feeds'
|
||||
import {makeDvmRequest} from '@welshman/dvm'
|
||||
import {makeSecret, Nip01Signer} from '@welshman/signer'
|
||||
import {pubkey, signer} from './session'
|
||||
import {getFilterSelections} from './router'
|
||||
import {wotGraph, maxWot, getFollows, getNetwork, getFollowers} from './wot'
|
||||
import {load} from './core'
|
||||
|
||||
export const feedLoader = new FeedLoader({
|
||||
request: async ({filters = [{}], relays = [], onEvent}) => {
|
||||
if (relays.length > 0) {
|
||||
await load({onEvent, filters, relays})
|
||||
} else {
|
||||
await Promise.all(
|
||||
getFilterSelections(filters)
|
||||
.map(opts => load({onEvent, ...opts}))
|
||||
)
|
||||
}
|
||||
},
|
||||
requestDVM: async ({kind, onEvent, ...request}) => {
|
||||
const tags = [...request.tags || [], ["expiration", String(now() + 5)]]
|
||||
const $signer = signer.get() || new Nip01Signer(makeSecret())
|
||||
const event = await $signer.sign(createEvent(kind, {tags}))
|
||||
const relays =
|
||||
request.relays
|
||||
? ctx.app.router.fromRelays(request.relays).getUrls()
|
||||
: ctx.app.router.FromPubkeys(getPubkeyTagValues(tags)).getUrls()
|
||||
|
||||
const req = makeDvmRequest({event, relays})
|
||||
|
||||
await new Promise<void>(resolve => {
|
||||
req.emitter.on("result", (url, event) => {
|
||||
onEvent(event)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
getPubkeysForScope: (scope: string) => {
|
||||
const $pubkey = pubkey.get()
|
||||
|
||||
if (!$pubkey) {
|
||||
return []
|
||||
}
|
||||
|
||||
switch (scope) {
|
||||
case Scope.Self: return [$pubkey]
|
||||
case Scope.Follows: return getFollows($pubkey)
|
||||
case Scope.Network: return getNetwork($pubkey)
|
||||
case Scope.Followers: return getFollowers($pubkey)
|
||||
default: return []
|
||||
}
|
||||
},
|
||||
getPubkeysForWOTRange: (min, max) => {
|
||||
const pubkeys = []
|
||||
const thresholdMin = maxWot.get() * min
|
||||
const thresholdMax = maxWot.get() * max
|
||||
|
||||
for (const [tpk, score] of wotGraph.get().entries()) {
|
||||
if (score >= thresholdMin && score <= thresholdMax) {
|
||||
pubkeys.push(tpk)
|
||||
}
|
||||
}
|
||||
|
||||
return pubkeys
|
||||
},
|
||||
})
|
||||
@@ -108,5 +108,7 @@ export const deriveHandleForPubkey = (pubkey: string, request: Partial<Subscribe
|
||||
}
|
||||
)
|
||||
|
||||
export const displayHandle = (handle: Handle) =>
|
||||
handle.nip05.startsWith("_@") ? last(handle.nip05.split("@")) : handle.nip05
|
||||
export const displayNip05 = (nip05: string) =>
|
||||
(nip05?.startsWith("_@") ? last(nip05.split("@")) : nip05)
|
||||
|
||||
export const displayHandle = (handle: Handle) => displayNip05(handle.nip05)
|
||||
|
||||
@@ -2,6 +2,7 @@ export * from './context'
|
||||
export * from './core'
|
||||
export * from './collection'
|
||||
export * from './commands'
|
||||
export * from './feeds'
|
||||
export * from './freshness'
|
||||
export * from './follows'
|
||||
export * from './handles'
|
||||
|
||||
+19
-1
@@ -1,6 +1,6 @@
|
||||
import {throttle} from 'throttle-debounce'
|
||||
import {derived, writable} from 'svelte/store'
|
||||
import {addToMapKey, inc, dec} from '@welshman/lib'
|
||||
import {max, addToMapKey, inc, dec} from '@welshman/lib'
|
||||
import {getListTags, getPubkeyTagValues} from '@welshman/util'
|
||||
import {throttled, withGetter} from '@welshman/store'
|
||||
import {pubkey} from './session'
|
||||
@@ -13,6 +13,22 @@ export const getFollows = (pubkey: string) =>
|
||||
export const getMutes = (pubkey: string) =>
|
||||
getPubkeyTagValues(getListTags(mutesByPubkey.get().get(pubkey)))
|
||||
|
||||
export const getNetwork = (pubkey: string) => {
|
||||
const pubkeys = new Set(getFollows(pubkey))
|
||||
const network = new Set<string>()
|
||||
|
||||
for (const follow of pubkeys) {
|
||||
for (const tpk of getFollows(follow)) {
|
||||
if (!pubkeys.has(tpk)) {
|
||||
network.add(tpk)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Array.from(network)
|
||||
}
|
||||
|
||||
|
||||
export const followersByPubkey = withGetter(
|
||||
derived(
|
||||
throttled(1000, follows),
|
||||
@@ -61,6 +77,8 @@ export const getFollowsWhoMute = (pubkey: string, target: string) =>
|
||||
|
||||
export const wotGraph = withGetter(writable(new Map<string, number>()))
|
||||
|
||||
export const maxWot = withGetter(derived(wotGraph, $g => max(Array.from($g.values()))))
|
||||
|
||||
const buildGraph = throttle(1000, () => {
|
||||
const $pubkey = pubkey.get()
|
||||
const $graph = new Map<string, number>()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {inc, max, min, now} from '@welshman/lib'
|
||||
import {inc, omitVals, max, min, now} from '@welshman/lib'
|
||||
import type {TrustedEvent, Filter} from '@welshman/util'
|
||||
import {EPOCH, trimFilters, guessFilterDelta} from '@welshman/util'
|
||||
import type {Feed, RequestItem, FeedOptions} from './core'
|
||||
@@ -98,7 +98,7 @@ export class FeedLoader {
|
||||
|
||||
let count = 0
|
||||
|
||||
await this.options.request({
|
||||
await this.options.request(omitVals([undefined], {
|
||||
relays,
|
||||
filters: trimFilters(requestFilters),
|
||||
onEvent: (event: TrustedEvent) => {
|
||||
@@ -106,7 +106,7 @@ export class FeedLoader {
|
||||
until = Math.min(until, event.created_at - 1)
|
||||
onEvent?.(event)
|
||||
},
|
||||
})
|
||||
}))
|
||||
|
||||
if (useWindowing) {
|
||||
if (since === minSince) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@welshman/lib",
|
||||
"version": "0.0.19",
|
||||
"version": "0.0.20",
|
||||
"author": "hodlbod",
|
||||
"license": "MIT",
|
||||
"description": "A collection of utilities.",
|
||||
|
||||
@@ -47,6 +47,18 @@ export const omit = <T extends Record<string, any>>(ks: string[], x: T) => {
|
||||
return r
|
||||
}
|
||||
|
||||
export const omitVals = <T extends Record<string, any>>(xs: any[], x: T) => {
|
||||
const r: Record<string, any> = {}
|
||||
|
||||
for (const [k, v] of Object.entries(x)) {
|
||||
if (!xs.includes(v)) {
|
||||
r[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
return r as T
|
||||
}
|
||||
|
||||
export const pick = <T extends Record<string, any>>(ks: string[], x: T) => {
|
||||
const r: T = {...x}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user