Add default feed loader to app
This commit is contained in:
Generated
+2
@@ -3639,6 +3639,8 @@
|
|||||||
"version": "0.0.11",
|
"version": "0.0.11",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@welshman/dvm": "~0.0.9",
|
||||||
|
"@welshman/feeds": "~0.0.19",
|
||||||
"@welshman/lib": "~0.0.19",
|
"@welshman/lib": "~0.0.19",
|
||||||
"@welshman/net": "~0.0.24",
|
"@welshman/net": "~0.0.24",
|
||||||
"@welshman/signer": "~0.0.7",
|
"@welshman/signer": "~0.0.7",
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@welshman/lib": "~0.0.19",
|
"@welshman/lib": "~0.0.19",
|
||||||
|
"@welshman/feeds": "~0.0.19",
|
||||||
|
"@welshman/dvm": "~0.0.9",
|
||||||
"@welshman/net": "~0.0.24",
|
"@welshman/net": "~0.0.24",
|
||||||
"@welshman/signer": "~0.0.7",
|
"@welshman/signer": "~0.0.7",
|
||||||
"@welshman/store": "~0.0.9",
|
"@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) =>
|
export const displayNip05 = (nip05: string) =>
|
||||||
handle.nip05.startsWith("_@") ? last(handle.nip05.split("@")) : handle.nip05
|
(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 './core'
|
||||||
export * from './collection'
|
export * from './collection'
|
||||||
export * from './commands'
|
export * from './commands'
|
||||||
|
export * from './feeds'
|
||||||
export * from './freshness'
|
export * from './freshness'
|
||||||
export * from './follows'
|
export * from './follows'
|
||||||
export * from './handles'
|
export * from './handles'
|
||||||
|
|||||||
+19
-1
@@ -1,6 +1,6 @@
|
|||||||
import {throttle} from 'throttle-debounce'
|
import {throttle} from 'throttle-debounce'
|
||||||
import {derived, writable} from 'svelte/store'
|
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 {getListTags, getPubkeyTagValues} from '@welshman/util'
|
||||||
import {throttled, withGetter} from '@welshman/store'
|
import {throttled, withGetter} from '@welshman/store'
|
||||||
import {pubkey} from './session'
|
import {pubkey} from './session'
|
||||||
@@ -13,6 +13,22 @@ export const getFollows = (pubkey: string) =>
|
|||||||
export const getMutes = (pubkey: string) =>
|
export const getMutes = (pubkey: string) =>
|
||||||
getPubkeyTagValues(getListTags(mutesByPubkey.get().get(pubkey)))
|
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(
|
export const followersByPubkey = withGetter(
|
||||||
derived(
|
derived(
|
||||||
throttled(1000, follows),
|
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 wotGraph = withGetter(writable(new Map<string, number>()))
|
||||||
|
|
||||||
|
export const maxWot = withGetter(derived(wotGraph, $g => max(Array.from($g.values()))))
|
||||||
|
|
||||||
const buildGraph = throttle(1000, () => {
|
const buildGraph = throttle(1000, () => {
|
||||||
const $pubkey = pubkey.get()
|
const $pubkey = pubkey.get()
|
||||||
const $graph = new Map<string, number>()
|
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 type {TrustedEvent, Filter} from '@welshman/util'
|
||||||
import {EPOCH, trimFilters, guessFilterDelta} from '@welshman/util'
|
import {EPOCH, trimFilters, guessFilterDelta} from '@welshman/util'
|
||||||
import type {Feed, RequestItem, FeedOptions} from './core'
|
import type {Feed, RequestItem, FeedOptions} from './core'
|
||||||
@@ -98,7 +98,7 @@ export class FeedLoader {
|
|||||||
|
|
||||||
let count = 0
|
let count = 0
|
||||||
|
|
||||||
await this.options.request({
|
await this.options.request(omitVals([undefined], {
|
||||||
relays,
|
relays,
|
||||||
filters: trimFilters(requestFilters),
|
filters: trimFilters(requestFilters),
|
||||||
onEvent: (event: TrustedEvent) => {
|
onEvent: (event: TrustedEvent) => {
|
||||||
@@ -106,7 +106,7 @@ export class FeedLoader {
|
|||||||
until = Math.min(until, event.created_at - 1)
|
until = Math.min(until, event.created_at - 1)
|
||||||
onEvent?.(event)
|
onEvent?.(event)
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
if (useWindowing) {
|
if (useWindowing) {
|
||||||
if (since === minSince) {
|
if (since === minSince) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@welshman/lib",
|
"name": "@welshman/lib",
|
||||||
"version": "0.0.19",
|
"version": "0.0.20",
|
||||||
"author": "hodlbod",
|
"author": "hodlbod",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "A collection of utilities.",
|
"description": "A collection of utilities.",
|
||||||
|
|||||||
@@ -47,6 +47,18 @@ export const omit = <T extends Record<string, any>>(ks: string[], x: T) => {
|
|||||||
return r
|
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) => {
|
export const pick = <T extends Record<string, any>>(ks: string[], x: T) => {
|
||||||
const r: T = {...x}
|
const r: T = {...x}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user