forked from coracle/flotilla
Switch to pnpm, use new welshman stuff
This commit is contained in:
+18
-104
@@ -7,51 +7,23 @@
|
||||
import {dev} from "$app/environment"
|
||||
import {goto} from "$app/navigation"
|
||||
import {bytesToHex, hexToBytes} from "@noble/hashes/utils"
|
||||
import {
|
||||
identity,
|
||||
sleep,
|
||||
take,
|
||||
sortBy,
|
||||
defer,
|
||||
ago,
|
||||
now,
|
||||
HOUR,
|
||||
WEEK,
|
||||
MONTH,
|
||||
Worker,
|
||||
} from "@welshman/lib"
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import {
|
||||
MESSAGE,
|
||||
PROFILE,
|
||||
DELETE,
|
||||
REACTION,
|
||||
ZAP_RESPONSE,
|
||||
FOLLOWS,
|
||||
RELAYS,
|
||||
INBOX_RELAYS,
|
||||
WRAP,
|
||||
getPubkeyTagValues,
|
||||
getListTags,
|
||||
} from "@welshman/util"
|
||||
import {identity, sleep, defer, ago, WEEK, TaskQueue} from "@welshman/lib"
|
||||
import type {TrustedEvent, StampedEvent} from "@welshman/util"
|
||||
import {WRAP} from "@welshman/util"
|
||||
import {Nip46Broker, getPubkey, makeSecret} from "@welshman/signer"
|
||||
import type {Socket} from "@welshman/net"
|
||||
import {request, defaultSocketPolicies, makeSocketPolicyAuth} from "@welshman/net"
|
||||
import {
|
||||
relays,
|
||||
handles,
|
||||
loadRelay,
|
||||
db,
|
||||
initStorage,
|
||||
repository,
|
||||
pubkey,
|
||||
plaintext,
|
||||
freshness,
|
||||
storageAdapters,
|
||||
tracker,
|
||||
defaultStorageAdapters,
|
||||
session,
|
||||
signer,
|
||||
dropSession,
|
||||
getRelayUrls,
|
||||
subscribe,
|
||||
userInboxRelaySelections,
|
||||
addSession,
|
||||
} from "@welshman/app"
|
||||
@@ -140,78 +112,20 @@
|
||||
}
|
||||
})
|
||||
|
||||
initStorage("flotilla", 5, {
|
||||
relays: storageAdapters.fromCollectionStore("url", relays, {throttle: 3000}),
|
||||
handles: storageAdapters.fromCollectionStore("nip05", handles, {throttle: 3000}),
|
||||
freshness: storageAdapters.fromObjectStore(freshness, {
|
||||
throttle: 3000,
|
||||
migrate: (data: {key: string; value: number}[]) => {
|
||||
const cutoff = ago(HOUR)
|
||||
|
||||
return data.filter(({value}) => value > cutoff)
|
||||
},
|
||||
}),
|
||||
plaintext: storageAdapters.fromObjectStore(plaintext, {
|
||||
throttle: 3000,
|
||||
migrate: (data: {key: string; value: number}[]) => data.slice(0, 10_000),
|
||||
}),
|
||||
events2: storageAdapters.fromRepositoryAndTracker(repository, tracker, {
|
||||
throttle: 3000,
|
||||
migrate: (events: TrustedEvent[]) => {
|
||||
if (events.length < 15_000) {
|
||||
return events
|
||||
}
|
||||
|
||||
const NEVER_KEEP = 0
|
||||
const ALWAYS_KEEP = Infinity
|
||||
const reactionKinds = [REACTION, ZAP_RESPONSE, DELETE]
|
||||
const metaKinds = [PROFILE, FOLLOWS, RELAYS, INBOX_RELAYS]
|
||||
const sessionKeys = new Set(Object.keys(app.sessions.get()))
|
||||
const userFollows = new Set(getPubkeyTagValues(getListTags(get(app.userFollows))))
|
||||
const maxWot = get(app.maxWot)
|
||||
|
||||
const scoreEvent = (e: TrustedEvent) => {
|
||||
const isFollowing = userFollows.has(e.pubkey)
|
||||
|
||||
// No need to keep a record of everyone who follows the current user
|
||||
if (e.kind === FOLLOWS && !isFollowing) return NEVER_KEEP
|
||||
|
||||
// Drop room messages after a month, re-load on demand
|
||||
if (e.kind === MESSAGE && e.created_at < ago(MONTH)) return NEVER_KEEP
|
||||
|
||||
// Always keep stuff by or tagging a signed in user
|
||||
if (sessionKeys.has(e.pubkey)) return ALWAYS_KEEP
|
||||
if (e.tags.some(t => sessionKeys.has(t[1]))) return ALWAYS_KEEP
|
||||
|
||||
// Get rid of irrelevant messages, reactions, and likes
|
||||
if (e.wrap || e.kind === 4 || e.kind === WRAP) return NEVER_KEEP
|
||||
if (reactionKinds.includes(e.kind)) return NEVER_KEEP
|
||||
|
||||
// If the user follows this person, use max wot score
|
||||
let score = isFollowing ? maxWot : app.getUserWotScore(e.pubkey)
|
||||
|
||||
// Inflate the score for profiles/relays/follows to avoid redundant fetches
|
||||
// Demote non-metadata type events, and introduce recency bias
|
||||
score *= metaKinds.includes(e.kind) ? 2 : e.created_at / now()
|
||||
|
||||
return score
|
||||
}
|
||||
|
||||
return take(
|
||||
10_000,
|
||||
sortBy(e => -scoreEvent(e), events),
|
||||
)
|
||||
},
|
||||
}),
|
||||
}).then(async () => {
|
||||
initStorage("flotilla", 6, defaultStorageAdapters).then(async () => {
|
||||
await sleep(300)
|
||||
ready.resolve()
|
||||
})
|
||||
|
||||
// Unwrap gift wraps as they come in, but throttled
|
||||
const unwrapper = new Worker<TrustedEvent>({chunkSize: 10})
|
||||
defaultSocketPolicies.push(
|
||||
makeSocketPolicyAuth({
|
||||
sign: (event: StampedEvent) => signer.get()?.sign(event),
|
||||
shouldAuth: (socket: Socket) => true,
|
||||
}),
|
||||
)
|
||||
|
||||
unwrapper.addGlobalHandler(ensureUnwrapped)
|
||||
// Unwrap gift wraps as they come in, but throttled
|
||||
const unwrapper = new TaskQueue<TrustedEvent>({batchSize: 10, processItem: ensureUnwrapped})
|
||||
|
||||
repository.on("update", ({added}) => {
|
||||
if (!$canDecrypt) {
|
||||
@@ -244,14 +158,14 @@
|
||||
})
|
||||
|
||||
// Listen for chats, populate chat-based notifications
|
||||
let chatsSub: any
|
||||
let chatsReq: any
|
||||
|
||||
derived([pubkey, canDecrypt, userInboxRelaySelections], identity).subscribe(
|
||||
([$pubkey, $canDecrypt, $userInboxRelaySelections]) => {
|
||||
chatsSub?.close()
|
||||
chatsReq?.close()
|
||||
|
||||
if ($pubkey && $canDecrypt) {
|
||||
chatsSub = subscribe({
|
||||
chatsReq = request({
|
||||
filters: [
|
||||
{kinds: [WRAP], "#p": [$pubkey], since: ago(WEEK, 2)},
|
||||
{kinds: [WRAP], "#p": [$pubkey], limit: 100},
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import * as nip19 from "nostr-tools/nip19"
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import {Address, getIdFilters, getTagValue} from "@welshman/util"
|
||||
import {load} from "@welshman/app"
|
||||
import {request, RequestEvent} from "@welshman/net"
|
||||
import {page} from "$app/stores"
|
||||
import {goto} from "$app/navigation"
|
||||
import {scrollToEvent} from "@lib/html"
|
||||
@@ -21,26 +21,29 @@
|
||||
|
||||
let found = false
|
||||
|
||||
load({
|
||||
const req = request({
|
||||
autoClose: true,
|
||||
filters: getIdFilters([type === "nevent" ? data.id : Address.fromNaddr(bech32).toString()]),
|
||||
relays: data.relays,
|
||||
onEvent: (event: TrustedEvent) => {
|
||||
found = true
|
||||
})
|
||||
|
||||
if (event.kind === 9) {
|
||||
goto(makeRoomPath(data.relays[0], getTagValue("h", event.tags)!), {replaceState: true})
|
||||
scrollToEvent(event.id)
|
||||
} else if (event.kind === 11) {
|
||||
goto(makeThreadPath(data.relays[0], event.id), {replaceState: true})
|
||||
} else {
|
||||
goto("/", {replaceState: true})
|
||||
}
|
||||
},
|
||||
onComplete: () => {
|
||||
if (!found) {
|
||||
goto("/", {replaceState: true})
|
||||
}
|
||||
},
|
||||
req.on(RequestEvent.Event, (event: TrustedEvent) => {
|
||||
found = true
|
||||
|
||||
if (event.kind === 9) {
|
||||
goto(makeRoomPath(data.relays[0], getTagValue("h", event.tags)!), {replaceState: true})
|
||||
scrollToEvent(event.id)
|
||||
} else if (event.kind === 11) {
|
||||
goto(makeThreadPath(data.relays[0], event.id), {replaceState: true})
|
||||
} else {
|
||||
goto("/", {replaceState: true})
|
||||
}
|
||||
})
|
||||
|
||||
req.on(RequestEvent.Close, () => {
|
||||
if (!found) {
|
||||
goto("/", {replaceState: true})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<script lang="ts">
|
||||
import {page} from "$app/stores"
|
||||
import {ctx} from "@welshman/lib"
|
||||
import {WRAP} from "@welshman/util"
|
||||
import {pubkey} from "@welshman/app"
|
||||
import {pubkey, Router} from "@welshman/app"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Page from "@lib/components/Page.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
@@ -25,7 +24,7 @@
|
||||
|
||||
const promise = pullConservatively({
|
||||
filters: [{kinds: [WRAP], "#p": [$pubkey!]}],
|
||||
relays: ctx.app.router.UserInbox().getUrls(),
|
||||
relays: Router.get().UserInbox().getUrls(),
|
||||
})
|
||||
|
||||
let term = $state("")
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import {ctx} from "@welshman/lib"
|
||||
import {getListTags, createEvent, getPubkeyTagValues, MUTES} from "@welshman/util"
|
||||
import {pubkey, signer, userMutes, tagPubkey, publishThunk} from "@welshman/app"
|
||||
import {pubkey, Router, signer, userMutes, tagPubkey, publishThunk} from "@welshman/app"
|
||||
import {preventDefault} from "@lib/html"
|
||||
import Field from "@lib/components/Field.svelte"
|
||||
import FieldInline from "@lib/components/FieldInline.svelte"
|
||||
@@ -22,12 +21,12 @@
|
||||
|
||||
publishThunk({
|
||||
event: createEvent(SETTINGS, {content}),
|
||||
relays: ctx.app.router.FromUser().getUrls(),
|
||||
relays: Router.get().FromUser().getUrls(),
|
||||
})
|
||||
|
||||
publishThunk({
|
||||
event: createEvent(MUTES, {tags: mutedPubkeys.map(tagPubkey)}),
|
||||
relays: ctx.app.router.FromUser().getUrls(),
|
||||
relays: Router.get().FromUser().getUrls(),
|
||||
})
|
||||
|
||||
pushToast({message: "Your settings have been saved!"})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import {nip19} from "nostr-tools"
|
||||
import * as nip19 from "nostr-tools/nip19"
|
||||
import {hexToBytes} from "@noble/hashes/utils"
|
||||
import {displayPubkey, displayProfile} from "@welshman/util"
|
||||
import {pubkey, session, displayNip05, deriveProfile} from "@welshman/app"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import {page} from "$app/stores"
|
||||
import {ago, MONTH} from "@welshman/lib"
|
||||
import {GROUPS, THREAD, COMMENT, MESSAGE, DELETE} from "@welshman/util"
|
||||
import {subscribe, load} from "@welshman/app"
|
||||
import {request, load} from "@welshman/net"
|
||||
import Page from "@lib/components/Page.svelte"
|
||||
import SecondaryNav from "@lib/components/SecondaryNav.svelte"
|
||||
import MenuSpace from "@app/components/MenuSpace.svelte"
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
// Load all groups for this space to populate navigation. It would be nice to sync, but relay29
|
||||
// is too picky about how requests are built.
|
||||
load({relays, filters: [{kinds: [GROUPS]}], delay: 0})
|
||||
load({relays, filters: [{kinds: [GROUPS]}]})
|
||||
|
||||
// Load threads, comments, and recent messages for user rooms to help with a quick page transition
|
||||
pullConservatively({
|
||||
@@ -69,10 +69,10 @@
|
||||
})
|
||||
|
||||
// Listen for deletes that would apply to messages we already have, and new groups
|
||||
const sub = subscribe({relays, filters: [{kinds: [DELETE, GROUPS], since}]})
|
||||
const req = request({relays, filters: [{kinds: [DELETE, GROUPS], since}]})
|
||||
|
||||
return () => {
|
||||
sub.close()
|
||||
req.close()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
import {page} from "$app/stores"
|
||||
import {sortBy, sleep} from "@welshman/lib"
|
||||
import {COMMENT, getTagValue} from "@welshman/util"
|
||||
import {repository, subscribe} from "@welshman/app"
|
||||
import {request} from "@welshman/net"
|
||||
import {repository} from "@welshman/app"
|
||||
import {deriveEvents} from "@welshman/store"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import PageBar from "@lib/components/PageBar.svelte"
|
||||
@@ -45,10 +46,10 @@
|
||||
let showReply = $state(false)
|
||||
|
||||
onMount(() => {
|
||||
const sub = subscribe({relays: [url], filters})
|
||||
const req = request({relays: [url], filters})
|
||||
|
||||
return () => {
|
||||
sub.close()
|
||||
req.close()
|
||||
setChecked($page.url.pathname)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
import {page} from "$app/stores"
|
||||
import {sortBy, sleep} from "@welshman/lib"
|
||||
import {COMMENT, getTagValue} from "@welshman/util"
|
||||
import {repository, subscribe} from "@welshman/app"
|
||||
import {repository} from "@welshman/app"
|
||||
import {request} from "@welshman/net"
|
||||
import {deriveEvents} from "@welshman/store"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import PageBar from "@lib/components/PageBar.svelte"
|
||||
@@ -42,10 +43,10 @@
|
||||
let showReply = $state(false)
|
||||
|
||||
onMount(() => {
|
||||
const sub = subscribe({relays: [url], filters})
|
||||
const req = request({relays: [url], filters})
|
||||
|
||||
return () => {
|
||||
sub.close()
|
||||
req.close()
|
||||
setChecked($page.url.pathname)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user