Merge multiple models into person

This commit is contained in:
Jonathan Staab 2023-09-05 13:45:43 -07:00
parent 5bd3075c67
commit 6af41363cd
9 changed files with 82 additions and 122 deletions

View File

@ -49,25 +49,6 @@ export type DisplayEvent = Event & {
matchesFilter?: boolean
}
export type Zapper = {
pubkey: string
lnurl: string
callback: string
minSendable: number
maxSendable: number
nostrPubkey: string
created_at: number
updated_at: number
}
export type Handle = {
profile: Record<string, any>
pubkey: string
address: string
created_at: number
updated_at: number
}
export type RelayInfo = {
contact?: string
description?: string
@ -91,32 +72,13 @@ export enum RelayMode {
Write = "write",
}
export type RelayPolicyEntry = {
export type RelayPolicy = {
url: string
read: boolean
write: boolean
}
export type RelayPolicy = {
pubkey: string
created_at: number
updated_at: number
relays: RelayPolicyEntry[]
}
export type GraphEntry = {
pubkey: string
updated_at: number
petnames_updated_at?: number
petnames?: string[][]
mutes_updated_at?: number
mutes?: string[][]
}
export type Profile = {
pubkey: string
created_at?: number
updated_at?: number
name?: string
nip05?: string
lud16?: string
@ -126,6 +88,38 @@ export type Profile = {
display_name?: string
}
export type Handle = {
profile: Record<string, any>
pubkey: string
address: string
}
export type Zapper = {
pubkey: string
lnurl: string
callback: string
minSendable: number
maxSendable: number
nostrPubkey: string
}
export type Person = {
pubkey: string
last_fetched?: number
profile_updated_at?: number
profile?: Profile
petnames_updated_at?: number
petnames?: string[][]
mutes_updated_at?: number
mutes?: string[][]
relays_updated_at?: number
relays: RelayPolicy[]
handle_updated_at?: number
handle: Handle
zapper_updated_at?: number
zapper: Handle
}
export type Channel = {
id: string
name?: string

View File

@ -5,3 +5,23 @@ import type {Event} from "src/engine2/model"
export const projections = new Worker<Event>({
getKey: prop("kind"),
})
export const updateKey = (key, timestamp, updates) => {
let record = key.get()
for (const [field, value] of Object.entries(updates)) {
const tsField = `${field}_updated_at`
const lastUpdated = record?.[tsField] || 0
if (timestamp > lastUpdated) {
record = {
...record,
[field]: value,
[tsField]: timestamp,
updated_at: Math.max(timestamp, record?.updated_at || 0),
}
}
}
key.set(record)
}

View File

@ -1,32 +1,15 @@
import {now} from "src/util/misc"
import {Tags} from "src/util/nostr"
import {socialGraph} from "src/engine2/state"
import {projections} from "src/engine2/projections/core"
import {people} from "src/engine2/state"
import {projections, updateKey} from "src/engine2/projections/core"
projections.addHandler(3, e => {
const entry = socialGraph.key(e.pubkey).get()
if (e.created_at < entry?.petnames_updated_at) {
return
}
socialGraph.key(e.pubkey).merge({
updated_at: now(),
petnames_updated_at: e.created_at,
updateKey(people.key(e.pubkey), e.created_at, {
petnames: Tags.from(e).type("p").all(),
})
})
projections.addHandler(10000, e => {
const entry = socialGraph.key(e.pubkey).get()
if (e.created_at < entry?.mutes_updated_at) {
return
}
socialGraph.key(e.pubkey).merge({
updated_at: now(),
mutes_updated_at: e.created_at,
updateKey(people.key(e.pubkey), e.created_at, {
mutes: Tags.from(e).type(["e", "p"]).all(),
})
})

View File

@ -2,10 +2,10 @@ import {uniqBy, prop, inc} from "ramda"
import {tryJson, now} from "src/util/misc"
import {warn} from "src/util/logger"
import {normalizeRelayUrl, isShareableRelay, Tags} from "src/util/nostr"
import type {RelayPolicyEntry} from "src/engine2/model"
import type {RelayPolicy} from "src/engine2/model"
import {RelayMode} from "src/engine2/model"
import {relays, relayPolicies} from "src/engine2/state"
import {projections} from "src/engine2/projections/core"
import {relays, people} from "src/engine2/state"
import {projections, updateKey} from "src/engine2/projections/core"
const addRelay = (url: string) => {
if (isShareableRelay(url)) {
@ -21,19 +21,10 @@ const addRelay = (url: string) => {
}
}
const setPolicy = (
{pubkey, created_at}: {pubkey: string; created_at: number},
relays: RelayPolicyEntry[]
) => {
const setPolicy = (e, relays: RelayPolicy[]) => {
if (relays?.length > 0) {
if (created_at < relayPolicies.key(pubkey).get()?.created_at) {
return
}
relayPolicies.key(pubkey).merge({
created_at,
updated_at: now(),
relays: uniqBy(prop("url"), relays).map((relay: RelayPolicyEntry) => {
updateKey(people.key(e.pubkey), e.created_at, {
relays: uniqBy(prop("url"), relays).map((relay: RelayPolicy) => {
addRelay(relay.url)
return {read: true, write: true, ...relay}
@ -49,7 +40,7 @@ projections.addHandler(2, e => {
projections.addHandler(3, e => {
setPolicy(
e,
tryJson<RelayPolicyEntry[]>(() => {
tryJson<RelayPolicy[]>(() => {
return Object.entries(JSON.parse(e.content || ""))
.filter(([url]) => isShareableRelay(url))
.map(([url, conditions]) => {
@ -60,7 +51,7 @@ projections.addHandler(3, e => {
return {url: normalizeRelayUrl(url), write, read}
})
}) as RelayPolicyEntry[]
}) as RelayPolicy[]
)
})

View File

@ -1,12 +1,11 @@
import {nth, map} from "ramda"
import {ensurePlural} from "hurdak"
import {derived} from "src/engine2/util/store"
import {socialGraph} from "src/engine2/state"
import {people} from "src/engine2/state"
export const derivePetnames = (pubkey: string) =>
socialGraph.key(pubkey).derived(g => g?.petnames || [])
export const derivePetnames = (pubkey: string) => people.key(pubkey).derived(g => g?.petnames || [])
export const deriveMutes = (pubkey: string) => socialGraph.key(pubkey).derived(g => g?.mutes || [])
export const deriveMutes = (pubkey: string) => people.key(pubkey).derived(g => g?.mutes || [])
export const deriveFollowsSet = (pubkeys: string | string[]) =>
derived(

View File

@ -5,7 +5,7 @@ import {findReplyId, findRootId, isShareableRelay, Tags} from "src/util/nostr"
import {derived} from "src/engine2/util/store"
import type {Event, Relay, RelayInfo} from "src/engine2/model"
import {RelayMode} from "src/engine2/model"
import {env, pool, relays, relayPolicies} from "src/engine2/state"
import {env, pool, relays, people} from "src/engine2/state"
import {stateKey} from "src/engine2/queries/session"
export const relayIsLowQuality = (url: string) =>
@ -29,7 +29,7 @@ export const getSearchRelays = () => {
}
export const getPubkeyRelays = (pubkey: string, mode: string = null) => {
const relays = relayPolicies.key(pubkey).get()?.relays || []
const relays = people.key(pubkey).get()?.relays || []
return mode ? relays.filter(prop(mode)) : relays
}

View File

@ -3,7 +3,7 @@ import {chunk, seconds, ensurePlural} from "hurdak"
import {personKinds, appDataKeys} from "src/util/nostr"
import {now} from "src/util/misc"
import type {Filter} from "src/engine2/model"
import {profiles, settings} from "src/engine2/state"
import {people, settings} from "src/engine2/state"
import {mergeHints, getPubkeyHints} from "src/engine2/queries"
import {Subscription} from "./subscription"
@ -26,10 +26,14 @@ export const getStalePubkeys = (pubkeys: string[]) => {
attemptedPubkeys.add(pubkey)
if (profiles.key(pubkey).get()?.updated_at || 0 > since) {
const key = people.key(pubkey)
if (key.get()?.last_fetched || 0 > since) {
continue
}
key.merge({last_fetched: now()})
stale.add(pubkey)
}

View File

@ -1,17 +1,6 @@
import {Pool} from "paravel"
import {collection, writable} from "src/engine2/util/store"
import type {
Event,
KeyState,
Topic,
List,
Profile,
GraphEntry,
Relay,
RelayPolicy,
Handle,
Zapper,
} from "src/engine2/model"
import type {Event, KeyState, Topic, List, Person, Relay} from "src/engine2/model"
// Synchronous stores
@ -27,12 +16,8 @@ export const alerts = collection<Event & {recipient: string}>("id")
export const events = collection<Event>("id")
export const topics = collection<Topic>("name")
export const lists = collection<List>("naddr")
export const profiles = collection<Profile>("pubkey")
export const socialGraph = collection<GraphEntry>("pubkey")
export const handles = collection<Handle>("pubkey")
export const zappers = collection<Zapper>("pubkey")
export const people = collection<Person>("pubkey")
export const relays = collection<Relay>("url")
export const relayPolicies = collection<RelayPolicy>("pubkey")
// Other stuff

View File

@ -29,35 +29,19 @@ export const storage = new Storage([
sort: sortByPubkeyWhitelist(prop("created_at")),
}),
new IndexedDBAdapter("topics", state.topics, {
max: 1000,
max: 10000,
sort: sortBy(prop("created_at")),
}),
new IndexedDBAdapter("lists", state.lists, {
max: 1000,
sort: sortByPubkeyWhitelist(prop("created_at")),
}),
new IndexedDBAdapter("profiles", state.profiles, {
max: 10000,
sort: sortByPubkeyWhitelist(prop("created_at")),
}),
new IndexedDBAdapter("socialGraph", state.socialGraph, {
new IndexedDBAdapter("people", state.people, {
max: 10000,
sort: sortByPubkeyWhitelist(prop("created_at")),
}),
new IndexedDBAdapter("handles", state.handles, {
max: 10000,
sort: sortByPubkeyWhitelist(prop("created_at")),
}),
new IndexedDBAdapter("zappers", state.zappers, {
max: 10000,
sort: sortByPubkeyWhitelist(prop("created_at")),
sort: sortByPubkeyWhitelist(prop("last_fetched")),
}),
new IndexedDBAdapter("relays", state.relays, {
max: 1000,
max: 10000,
sort: sortBy(prop("created_at")),
}),
new IndexedDBAdapter("relayPolicies", state.relayPolicies, {
max: 10000,
sort: sortByPubkeyWhitelist(prop("created_at")),
}),
])