diff --git a/src/app/components/AlertAdd.svelte b/src/app/components/AlertAdd.svelte
index b8f9210d..3eb07eee 100644
--- a/src/app/components/AlertAdd.svelte
+++ b/src/app/components/AlertAdd.svelte
@@ -1,7 +1,7 @@
diff --git a/src/app/components/NoteContentMinimalGoal.svelte b/src/app/components/NoteContentMinimalGoal.svelte
index ae768550..af9679d9 100644
--- a/src/app/components/NoteContentMinimalGoal.svelte
+++ b/src/app/components/NoteContentMinimalGoal.svelte
@@ -3,7 +3,7 @@
import {sum} from "@welshman/lib"
import type {Zap, TrustedEvent} from "@welshman/util"
import {getTagValue, fromMsats, ZAP_RESPONSE} from "@welshman/util"
- import {deriveEventsMapped} from "@welshman/store"
+ import {deriveItemsByKey, deriveArray} from "@welshman/store"
import {repository, getValidZap} from "@welshman/app"
import Bolt from "@assets/icons/bolt.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
@@ -14,11 +14,14 @@
const content = getTagValue("summary", props.event.tags)
const fakeEvent = {content, tags: props.event.tags}
- const zaps = deriveEventsMapped(repository, {
- filters: [{kinds: [ZAP_RESPONSE], "#e": [props.event.id]}],
- itemToEvent: item => item.response,
- eventToItem: (response: TrustedEvent) => getValidZap(response, props.event),
- })
+ const zaps = deriveArray(
+ deriveItemsByKey({
+ repository,
+ getKey: zap => zap.response.id,
+ filters: [{kinds: [ZAP_RESPONSE], "#e": [props.event.id]}],
+ eventToItem: (response: TrustedEvent) => getValidZap(response, props.event),
+ }),
+ )
const goalAmount = parseInt(getTagValue("amount", props.event.tags) || "0")
const zapAmount = $derived(fromMsats(sum($zaps.map(zap => zap.invoiceAmount))))
diff --git a/src/app/components/ProfileBadges.svelte b/src/app/components/ProfileBadges.svelte
index e95ab674..96df2cf2 100644
--- a/src/app/components/ProfileBadges.svelte
+++ b/src/app/components/ProfileBadges.svelte
@@ -3,13 +3,13 @@
import {load} from "@welshman/net"
import {Router} from "@welshman/router"
import type {Filter} from "@welshman/util"
- import {deriveEvents} from "@welshman/store"
+ import {deriveArray, deriveEventsById} from "@welshman/store"
import {formatTimestampRelative} from "@welshman/lib"
import {NOTE, ROOMS, COMMENT} from "@welshman/util"
import {repository, loadRelayList} from "@welshman/app"
import Button from "@lib/components/Button.svelte"
import ProfileSpaces from "@app/components/ProfileSpaces.svelte"
- import {deriveGroupList, getSpaceUrlsFromGroupLists, MESSAGE_KINDS} from "@app/core/state"
+ import {deriveGroupList, getSpaceUrlsFromGroupList, MESSAGE_KINDS} from "@app/core/state"
import {goToEvent} from "@app/util/routes"
import {pushModal} from "@app/util/modal"
@@ -20,7 +20,7 @@
const {pubkey, url}: Props = $props()
const filters: Filter[] = [{authors: [pubkey], limit: 1}]
- const events = deriveEvents(repository, {filters})
+ const events = deriveArray(deriveEventsById({repository, filters}))
const groupList = deriveGroupList(pubkey)
const spaceUrls = $derived(getSpaceUrlsFromGroupList($groupList))
diff --git a/src/app/components/ReactionSummary.svelte b/src/app/components/ReactionSummary.svelte
index a1bcb6b9..ecebae31 100644
--- a/src/app/components/ReactionSummary.svelte
+++ b/src/app/components/ReactionSummary.svelte
@@ -2,7 +2,7 @@
import cx from "classnames"
import {onMount} from "svelte"
import type {Snippet} from "svelte"
- import {groupBy, sum, uniq, uniqBy, batch, displayList} from "@welshman/lib"
+ import {groupBy, map, sum, uniq, uniqBy, batch, displayList} from "@welshman/lib"
import {
REPORT,
REACTION,
@@ -15,7 +15,7 @@
DELETE,
} from "@welshman/util"
import type {TrustedEvent, EventContent, Zap} from "@welshman/util"
- import {deriveEvents, deriveEventsMapped} from "@welshman/store"
+ import {deriveArray, deriveEventsById, deriveItemsByKey} from "@welshman/store"
import {load} from "@welshman/net"
import {pubkey, repository, getValidZap, displayProfileByPubkey} from "@welshman/app"
import {isMobile, preventDefault, stopPropagation} from "@lib/html"
@@ -46,19 +46,22 @@
children,
}: Props = $props()
- const reports = deriveEvents(repository, {
- filters: [{kinds: [REPORT], "#e": [event.id]}],
- })
+ const reports = deriveArray(
+ deriveEventsById({repository, filters: [{kinds: [REPORT], "#e": [event.id]}]}),
+ )
- const reactions = deriveEvents(repository, {
- filters: [{kinds: [REACTION], "#e": [event.id]}],
- })
+ const reactions = deriveArray(
+ deriveEventsById({repository, filters: [{kinds: [REACTION], "#e": [event.id]}]}),
+ )
- const zaps = deriveEventsMapped(repository, {
- filters: [{kinds: [ZAP_RESPONSE], "#e": [event.id]}],
- itemToEvent: item => item.response,
- eventToItem: (response: TrustedEvent) => getValidZap(response, event),
- })
+ const zaps = deriveArray(
+ deriveItemsByKey({
+ repository,
+ getKey: zap => zap.response.id,
+ filters: [{kinds: [ZAP_RESPONSE], "#e": [event.id]}],
+ eventToItem: (response: TrustedEvent) => getValidZap(response, event),
+ }),
+ )
const onReactionClick = (events: TrustedEvent[]) => {
const reaction = events.find(e => e.pubkey === $pubkey)
@@ -77,18 +80,18 @@
const onReportClick = () => pushModal(ReportDetails, {url, event})
- const reportReasons = $derived(uniq($reports.map(e => getTag("e", e.tags)?.[2])))
+ const reportReasons = $derived(uniq(map(e => getTag("e", e.tags)?.[2], $reports.values())))
const getReactionKey = (e: TrustedEvent) => getEmojiTag(e.content, e.tags)?.join("") || e.content
const groupedReactions = $derived(
groupBy(
getReactionKey,
- uniqBy(e => `${e.pubkey}${getReactionKey(e)}`, $reactions),
+ uniqBy(e => `${e.pubkey}${getReactionKey(e)}`, $reactions.values()),
),
)
- const groupedZaps = $derived(groupBy(e => getReactionKey(e.request), $zaps))
+ const groupedZaps = $derived(groupBy(e => getReactionKey(e.request), $zaps.values()))
onMount(() => {
const controller = new AbortController()
diff --git a/src/app/components/ReportDetails.svelte b/src/app/components/ReportDetails.svelte
index 6bf8b7ff..516692dc 100644
--- a/src/app/components/ReportDetails.svelte
+++ b/src/app/components/ReportDetails.svelte
@@ -1,7 +1,7 @@