Add lists/topics/labels

This commit is contained in:
Jonathan Staab 2023-09-09 12:17:42 -07:00
parent d5c4fcd227
commit 44847bd50c
8 changed files with 83 additions and 8 deletions

View File

@ -112,11 +112,11 @@ export type Person = {
mutes_updated_at?: number mutes_updated_at?: number
mutes?: string[][] mutes?: string[][]
relays_updated_at?: number relays_updated_at?: number
relays: RelayPolicy[] relays?: RelayPolicy[]
handle_updated_at?: number handle_updated_at?: number
handle: Handle handle?: Handle
zapper_updated_at?: number zapper_updated_at?: number
zapper: Zapper zapper?: Zapper
} }
export type Channel = { export type Channel = {
@ -142,14 +142,13 @@ export type Channel = {
export type Topic = { export type Topic = {
name: string name: string
count?: number count?: number
last_seen?: number
} }
export type List = { export type List = {
name: string name: string
naddr: string naddr: string
pubkey: string pubkey: string
tags_updated_at: number
tags: string[][] tags: string[][]
updated_at: number
created_at: number
deleted_at?: number
} }

View File

@ -1,4 +1,4 @@
import {identity, prop} from "ramda" import {prop} from "ramda"
import {Worker} from "src/engine2/util/worker" import {Worker} from "src/engine2/util/worker"
import type {Event} from "src/engine2/model" import type {Event} from "src/engine2/model"
@ -6,7 +6,7 @@ export const projections = new Worker<Event>({
getKey: prop("kind"), getKey: prop("kind"),
}) })
export const updateKey = (key, timestamp, updates, modify = identity) => { export const updateKey = (key, timestamp, updates, modify = (a: any) => a) => {
let record = key.get() let record = key.get()
for (const [field, value] of Object.entries(updates)) { for (const [field, value] of Object.entries(updates)) {

View File

@ -0,0 +1,13 @@
import {Tags} from "src/util/nostr"
import {deletes} from "src/engine2/state"
import {projections} from "src/engine2/projections/core"
projections.addHandler(5, e => {
Tags.from(e)
.type(["a", "e"])
.values()
.all()
.forEach(value => {
deletes.key(value).set({value})
})
})

View File

@ -5,5 +5,8 @@ import "./nip28"
import "./nip57" import "./nip57"
import "./nip65" import "./nip65"
import "./alerts" import "./alerts"
import "./deletes"
import "./lists"
import "./topics"
export * from "./core" export * from "./core"

View File

@ -0,0 +1,6 @@
import {labels} from "src/engine2/state"
import {projections} from "src/engine2/projections/core"
projections.addHandler(1985, e => {
labels.key(e.id).set(e)
})

View File

@ -0,0 +1,17 @@
import {nip19} from "nostr-tools"
import {mergeLeft} from "ramda"
import {Tags} from "src/util/nostr"
import type {Event} from "src/engine2/model"
import {lists} from "src/engine2/state"
import {projections, updateKey} from "src/engine2/projections/core"
projections.addHandler(30001, (e: Event) => {
const name = Tags.from(e).getMeta("d")
const naddr = nip19.naddrEncode({
identifier: name,
pubkey: e.pubkey,
kind: e.kind,
})
updateKey(lists.key(naddr), e.created_at, {tags: e.tags}, mergeLeft({name, pubkey: e.pubkey}))
})

View File

@ -0,0 +1,35 @@
import {nth, inc} from "ramda"
import {Tags} from "src/util/nostr"
import type {Event} from "src/engine2/model"
import {topics} from "src/engine2/state"
import {projections} from "src/engine2/projections/core"
const addTopic = (e, name) => {
if (name) {
const topic = topics.key(name)
topic.merge({
count: inc(topic.get()?.count || 0),
last_seen: e.created_at,
})
}
}
const processTopics = (e: Event) => {
const tagTopics = Tags.from(e).topics()
const contentTopics = Array.from(e.content.toLowerCase().matchAll(/#(\w{2,100})/g)).map(nth(1))
for (const name of tagTopics.concat(contentTopics)) {
addTopic(e, name)
}
}
projections.addHandler(1, processTopics)
projections.addHandler(42, processTopics)
projections.addHandler(1985, (e: Event) => {
for (const name of Tags.from(e).type("l").mark("#t").values().all()) {
addTopic(e, name)
}
})

View File

@ -14,6 +14,8 @@ export const alertsLastChecked = writable(0)
export const alerts = collection<Event & {recipient: string}>("id") export const alerts = collection<Event & {recipient: string}>("id")
export const events = collection<Event>("id") export const events = collection<Event>("id")
export const deletes = collection<{value: string}>("value")
export const labels = collection<Event>("id")
export const topics = collection<Topic>("name") export const topics = collection<Topic>("name")
export const lists = collection<List>("naddr") export const lists = collection<List>("naddr")
export const people = collection<Person>("pubkey") export const people = collection<Person>("pubkey")