Skip to content

WIP: rx-nostr#1786

Open
mouse484 wants to merge 6 commits intomainfrom
feat/rx-nostr-events
Open

WIP: rx-nostr#1786
mouse484 wants to merge 6 commits intomainfrom
feat/rx-nostr-events

Conversation

@mouse484
Copy link
Copy Markdown
Owner

@mouse484 mouse484 commented Mar 30, 2026

Summary by CodeRabbit

  • New Features

    • Real-time Nostr event streaming with automatic UI and cache synchronization (metadata, text notes, follow lists, reactions, relay lists).
  • Refactor

    • Query/loader plumbing migrated to a streaming-based request model; components and routes updated to consume the new reactive query APIs.
  • Chores

    • Added reactive and Nostr crypto libraries to support streaming integration.
  • Style

    • Enforced expanded naming rules via linter with allowed abbreviations.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

Replaces pool-based fetching with RxNostr streams and request factories; refactors query core to use queryClient + rxBackwardReq and return [query, setQuery]; exports several event schemas/types and query/setter tuples; wires RxNostr subscriptions at app bootstrap; updates callers and route loaders to the new API.

Changes

Cohort / File(s) Summary
Dependencies & Lint
eslint.config.js, package.json
Added unicorn/prevent-abbreviations rule with exceptions and an override for src/vite-env.d.ts; added deps @rx-nostr/crypto, nostr-typedef, rx-nostr, rxjs.
RxNostr & wiring
src/lib/nostr/rx-nostr.ts, src/main.tsx
New rxNostr, rxForwardReq, rxBackwardReq exports; app bootstrap subscribes/merges forward+backward streams, batches events, seeds a forward request, and extends router context with RxNostr artifacts.
Query core refactor
src/lib/nostr/query-helpers.ts, src/lib/nostr/hooks/use-nostr.ts
NostrQueryContext now uses queryClient + rxBackwardReq (relays optional); createQuery now returns [queryFn, setQueryFn], uses QueryObserver/abort signal, and setQueryFn writes parsed events into queryClient.
Kind schemas & queries
src/lib/nostr/kinds/0.ts, src/lib/nostr/kinds/1.ts, src/lib/nostr/kinds/3.ts, src/lib/nostr/kinds/7.ts, src/lib/nostr/kinds/10002.ts
Promoted several schemas to exported constants and added inferred event types; converted single-query exports to tuple exports ([Query, setQuery]) and added ReactionQuery.
Query key changes
src/lib/query-key.ts
Narrowed helper types and renamed optional param names for metadata and followlist key factories from id?: string to pubkey?: string (tuple shapes unchanged).
Route & loader updates
src/routes/(app)/(profile)/npub1{$id}.tsx, src/routes/(app)/(textnote)/nevent1{$id}.tsx, src/routes/(app)/home.tsx, src/routes/(app)/settings/relays.tsx
Loaders now destructure rxBackwardReq and queryClient from context and call queries with { queryClient, rxBackwardReq } instead of pool/relays.
Route setup changes
src/routes/(app)/route.tsx
Removed component-level pool.subscribe effect; moved relay configuration to beforeLoad using rxNostr.setDefaultRelays(...); updated imports.
Components & call-sites
src/components/NostrEvent.tsx, src/components/text-note/*
NostrEvent API changed to accept queryFunction/tuple queryOptions; call sites updated to use MetadataQuery, TextNoteQuery, and exported event types (e.g., TextNoteEvent).
Minor edits / TODOs
src/lib/nostr/hooks/use-nostr-events.ts
Added TODO comments about avoiding schema parsing in the hook; no runtime changes.

Sequence Diagram(s)

sequenceDiagram
    participant Browser as Client/Browser
    participant App as App Bootstrap
    participant RxNostr as RxNostr (rxForwardReq / rxBackwardReq)
    participant Relays as Relay Network
    participant Cache as TanStack Query Cache
    participant Routes as Route Loaders

    Note over App,RxNostr: App initializes rxNostr and subscriptions
    App->>RxNostr: start forward req (kinds 1,7 since 5m)
    RxNostr->>Relays: subscribe/request events (kinds 0,1,3,7)
    Relays-->>RxNostr: stream events
    RxNostr->>App: emit events
    App->>Cache: setQueryData per-kind (metadata, text, followlist, reaction)

    Routes->>RxNostr: emit backward request filters via rxBackwardReq
    RxNostr->>Relays: send filtered requests
    Relays-->>RxNostr: return matching events
    RxNostr->>Cache: update cache with results
    Cache-->>Routes: serve cached query data
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

released

🐰
I hopped through relays at dawn,
Brought streams that hum and sing,
Queries bloom where events are drawn,
Little hops update everything,
Squeak — the cache is spring! ✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'WIP: rx-nostr' is vague and uses non-descriptive generic terms ('WIP') that don't convey meaningful information about the specific changes made to the codebase. Replace 'WIP: rx-nostr' with a more descriptive title that summarizes the main change, such as 'Integrate rx-nostr for event subscription management' or 'Refactor Nostr queries to use rx-nostr and RxJS'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/rx-nostr-events

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Mar 30, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
astraea 2ddc291 Commit Preview URL

Branch Preview URL
Mar 30 2026, 01:13 PM

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/routes/(app)/home.tsx (1)

7-7: Minor: Extra space in function signature.

There's a double space between async and loader.

✨ Suggested fix
-  async  loader({ context: { queryClient, rxBackwardReq, pubkey } }) {
+  async loader({ context: { queryClient, rxBackwardReq, pubkey } }) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/`(app)/home.tsx at line 7, Remove the accidental double space in
the function declaration so the async keyword is directly followed by the
function name; edit the signature "async  loader({ context: { queryClient,
rxBackwardReq, pubkey } })" to "async loader(...)" (i.e., collapse the two
spaces to one) to match standard formatting and avoid linter/style warnings for
the loader function.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/nostr/query-helpers.ts`:
- Around line 67-85: The early-abort check inside queryFn currently calls reject
when signal.aborted but does not return, so execution continues to emit the
filter and subscribe; update queryFn to immediately return after rejecting when
signal.aborted (i.e., after reject(signal.reason) do a return), so the
subsequent rxBackwardReq.emit(filter, options), new QueryObserver(queryClient, {
queryKey }) and subscription setup are skipped; keep the existing abort event
listener/unsubscribe logic intact.
- Around line 68-85: The Promise can hang if no event arrives because you only
resolve on next; modify the subscription created by new
QueryObserver(...).subscribe to use the full observer form ({ next, error,
complete }) or add listeners to rxBackwardReq's completion so that on complete
you unsubscribe, remove the abort listener, and reject(new Error('NotFound' or
'Query completed without result')), and on error reject with that error; also
ensure abort handler cleans up the complete/error handlers and that you remove
the signal event listener after resolution/rejection. Target symbols:
QueryObserver, observer.subscribe, unsubscribe, rxBackwardReq.emit, and the
signal abort handler.

In `@src/main.tsx`:
- Around line 73-76: The emit call rxForwardReq.emit({...}) is executed at
module load before relays are configured; move or defer this emission so it runs
after rxNostr.setDefaultRelays() has been called (e.g., inside the router
route's beforeLoad hook or any initialization that runs after router/context
setup). Locate the module-level rxForwardReq.emit invocation and remove or guard
it, then add an emission point in the route beforeLoad (or a post-relay-setup
initializer) so rxNostr has default relays configured before calling
rxForwardReq.emit; keep the same event payload and ensure it uses the existing
rxNostr and rxForwardReq instances.

---

Nitpick comments:
In `@src/routes/`(app)/home.tsx:
- Line 7: Remove the accidental double space in the function declaration so the
async keyword is directly followed by the function name; edit the signature
"async  loader({ context: { queryClient, rxBackwardReq, pubkey } })" to "async
loader(...)" (i.e., collapse the two spaces to one) to match standard formatting
and avoid linter/style warnings for the loader function.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ca47d6f6-5a11-4dc9-a3d0-61b74573866a

📥 Commits

Reviewing files that changed from the base of the PR and between 472e99e and 0d1acc7.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (14)
  • eslint.config.js
  • package.json
  • src/lib/nostr/hooks/use-nostr.ts
  • src/lib/nostr/kinds/0.ts
  • src/lib/nostr/kinds/3.ts
  • src/lib/nostr/query-helpers.ts
  • src/lib/nostr/rx-nostr.ts
  • src/lib/query-key.ts
  • src/main.tsx
  • src/routes/(app)/(profile)/npub1{$id}.tsx
  • src/routes/(app)/(textnote)/nevent1{$id}.tsx
  • src/routes/(app)/home.tsx
  • src/routes/(app)/route.tsx
  • src/routes/(app)/settings/relays.tsx

Comment on lines +68 to +85
return new Promise<z.infer<Schema>>((resolve, reject) => {
if (signal.aborted) {
reject(signal.reason)
}
const options = relays ? { relays } : undefined
rxBackwardReq.emit(filter, options)
const observer = new QueryObserver(queryClient, { queryKey })
const unsubscribe = observer.subscribe((result) => {
if (result.data !== undefined) {
resolve(result.data as z.infer<Schema>)
}
})

signal.addEventListener('abort', () => {
unsubscribe()
reject(new Error('Query aborted'))
}, { signal })
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

How does rx-nostr RxBackwardReq signal end of stored events (EOSE)?

💡 Result:

In rx-nostr, RxBackwardReq (created via createRxBackwardReq) is designed for the "Backward Strategy," which collects past events from relays. It signals the end of stored events (EOSE) by completing the RxJS Observable subscription when an EOSE message is received from the relay for the corresponding subscription ID. This is shown in usage examples where developers subscribe to rxNostr.use(rxBackwardReq.pipe(...)) and use the complete callback to resolve promises or handle the end of historical event delivery, as rx-nostr automatically manages sending CLOSE after EOSE and handles the protocol details transparently per NIP-01.

Citations:


🏁 Script executed:

# First, let's look at the full function context around lines 68-85
cat -n src/lib/nostr/query-helpers.ts | head -100 | tail -50

Repository: mouse484/astraea

Length of output: 1898


🏁 Script executed:

# Check the full file size to understand scope
wc -l src/lib/nostr/query-helpers.ts

Repository: mouse484/astraea

Length of output: 93


🏁 Script executed:

# Look at the imports and setup
head -50 src/lib/nostr/query-helpers.ts

Repository: mouse484/astraea

Length of output: 1378


🏁 Script executed:

# Search for where rxBackwardReq is used and subscribed to
rg "rxBackwardReq" -A 3 -B 3 --type ts --type tsx

Repository: mouse484/astraea

Length of output: 87


🏁 Script executed:

# Look for EOSE handling in the codebase
rg "EOSE|eose" --type ts --type tsx

Repository: mouse484/astraea

Length of output: 87


🏁 Script executed:

# Search for where the query cache gets populated from rxBackwardReq
rg "queryClient.*setQueryData|mutate|setInfiniteQueryData" src/lib/nostr --type ts

Repository: mouse484/astraea

Length of output: 42


🏁 Script executed:

# Search for where rxBackwardReq is used and subscribed to
rg "rxBackwardReq" -A 3 -B 3

Repository: mouse484/astraea

Length of output: 6853


🏁 Script executed:

# Look for EOSE handling in the codebase
rg "EOSE|eose"

Repository: mouse484/astraea

Length of output: 42


🏁 Script executed:

# Search for where the query cache gets populated from rxBackwardReq
rg "queryClient.*setQueryData|mutate|setInfiniteQueryData" src/lib/nostr

Repository: mouse484/astraea

Length of output: 42


🏁 Script executed:

# Look at the full subscription in main.tsx
cat -n src/main.tsx | grep -A 20 "rxNostr.use(rxBackwardReq"

Repository: mouse484/astraea

Length of output: 930


🏁 Script executed:

# Search for setQueryData calls
rg "setQueryData"

Repository: mouse484/astraea

Length of output: 643


🏁 Script executed:

# Find the use-nostr-events hook
find . -name "*use-nostr*" -o -name "*nostr-events*" | head -20

Repository: mouse484/astraea

Length of output: 136


🏁 Script executed:

# Look at use-nostr-events hook mentioned in learnings
cat -n src/lib/nostr/hooks/use-nostr-events.ts

Repository: mouse484/astraea

Length of output: 2394


🏁 Script executed:

# Check if there's any EOSE or complete handler registered anywhere
rg "complete|finalize|EOSE"

Repository: mouse484/astraea

Length of output: 42


🏁 Script executed:

# Look for error handling in the rxBackwardReq subscription
cat -n src/main.tsx | grep -A 30 "subscribe"

Repository: mouse484/astraea

Length of output: 1318


Query will hang indefinitely if the requested event doesn't exist.

The QueryObserver only resolves when result.data !== undefined. While the root subscription in src/main.tsx handles incoming events, there's no error or complete handler for when rxBackwardReq completes (after EOSE is received from relays). If no matching event arrives before EOSE, the Promise never resolves or rejects. Consider adding a complete/error handler to the rxBackwardReq subscription or implementing a timeout to reject with a "not found" error.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/nostr/query-helpers.ts` around lines 68 - 85, The Promise can hang if
no event arrives because you only resolve on next; modify the subscription
created by new QueryObserver(...).subscribe to use the full observer form ({
next, error, complete }) or add listeners to rxBackwardReq's completion so that
on complete you unsubscribe, remove the abort listener, and reject(new
Error('NotFound' or 'Query completed without result')), and on error reject with
that error; also ensure abort handler cleans up the complete/error handlers and
that you remove the signal event listener after resolution/rejection. Target
symbols: QueryObserver, observer.subscribe, unsubscribe, rxBackwardReq.emit, and
the signal abort handler.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/main.tsx (1)

32-66: Consider adding error handling to the subscription.

The merged subscription has no error handler. If the rx-nostr stream errors, it will silently fail. Consider adding an error callback for observability.

♻️ Suggested improvement
 merge(
   rxNostr.use(rxForwardReq),
   rxNostr.use(rxBackwardReq.pipe(bufferTime(1000), batch())),
 )
-  .subscribe(({ event }) => {
+  .subscribe({
+    next: ({ event }) => {
       // TODO: kindによってのsetQueryDataの振り分けロジックを検討し改善する
       switch (event.kind) {
         // ... existing cases
       }
-  })
+    },
+    error: (err) => console.error('RxNostr subscription error:', err),
+  })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main.tsx` around lines 32 - 66, The merged observable created from
merge(rxNostr.use(rxForwardReq),
rxNostr.use(rxBackwardReq.pipe(bufferTime(1000), batch()))) is subscribed with
only a next handler so stream errors will be swallowed; update the subscribe
call on that merged stream to include an error callback (or use subscribe({
next, error, complete })) that logs the error (e.g., via console.error or your
app logger) and performs any cleanup/recovery (like invalidating or refetching
via queryClient if needed); modify the subscribe invocation that currently calls
setMetadataQuery, setTextNoteQuery, setFollowListQuery, and setReactionQuery to
provide this error handler.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/nostr/kinds/10002.ts`:
- Around line 15-19: The createQuery call for relayListQuery is missing the
required schema parameter; update the createQuery<RelayListEvent> invocation to
include schema: RelayListEventSchema so that setQueryFunction can call
schema.safeParse(event) safely; modify the relayListQuery object (the
createQuery(...) call) to pass RelayListEventSchema along with name, kind, and
filterKey.

---

Nitpick comments:
In `@src/main.tsx`:
- Around line 32-66: The merged observable created from
merge(rxNostr.use(rxForwardReq),
rxNostr.use(rxBackwardReq.pipe(bufferTime(1000), batch()))) is subscribed with
only a next handler so stream errors will be swallowed; update the subscribe
call on that merged stream to include an error callback (or use subscribe({
next, error, complete })) that logs the error (e.g., via console.error or your
app logger) and performs any cleanup/recovery (like invalidating or refetching
via queryClient if needed); modify the subscribe invocation that currently calls
setMetadataQuery, setTextNoteQuery, setFollowListQuery, and setReactionQuery to
provide this error handler.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 34bc6b84-579f-4d00-86f7-edcce0a56f6e

📥 Commits

Reviewing files that changed from the base of the PR and between 0d1acc7 and f4baed8.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (14)
  • package.json
  • src/components/text-note/TextNote.tsx
  • src/components/text-note/footer/Zap.tsx
  • src/lib/nostr/hooks/use-nostr-events.ts
  • src/lib/nostr/hooks/use-nostr.ts
  • src/lib/nostr/kinds/0.ts
  • src/lib/nostr/kinds/1.ts
  • src/lib/nostr/kinds/10002.ts
  • src/lib/nostr/kinds/3.ts
  • src/lib/nostr/kinds/7.ts
  • src/lib/nostr/query-helpers.ts
  • src/lib/query-key.ts
  • src/main.tsx
  • src/routes/(app)/(profile)/npub1{$id}.tsx
✅ Files skipped from review due to trivial changes (3)
  • src/lib/nostr/hooks/use-nostr-events.ts
  • src/components/text-note/footer/Zap.tsx
  • package.json
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/routes/(app)/(profile)/npub1{$id}.tsx
  • src/lib/nostr/hooks/use-nostr.ts
  • src/lib/nostr/kinds/0.ts
  • src/lib/query-key.ts
  • src/lib/nostr/kinds/3.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/NostrEvent.tsx`:
- Around line 8-11: The NostrEvent component currently cannot forward relay
hints because queryOptions only carries [id, setQueryKeyFunction] and useNostr()
has no relay context; update the shape of queryOptions to optionally include
relays (e.g. queryOptions: readonly [string, Parameters<QueryFunction<T>>[2], {
relays?: string[] }?]) or add a context-shaping callback prop on NostrEvent that
returns { relays } from the parsed nevent; then update NostrEvent to accept and
pass that relays object into useNostr()/the query context and update callers
(TextNoteContent.tsx) to supply the parsed nevent.decoded.relays into NostrEvent
so the existing query helper (queryFunction in query-helpers.ts which reads
context.relays) can use the hinted relays.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b4d76142-85c0-4eb5-a3f1-a341d4e67e4c

📥 Commits

Reviewing files that changed from the base of the PR and between cd6fd04 and 2ddc291.

📒 Files selected for processing (5)
  • src/components/NostrEvent.tsx
  • src/components/text-note/TextNote.tsx
  • src/components/text-note/TextNoteContent.tsx
  • src/lib/nostr/query-helpers.ts
  • src/lib/query-key.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/query-key.ts
  • src/lib/nostr/query-helpers.ts

Comment on lines +8 to +11
queryOptions: readonly [
string,
Parameters<QueryFunction<T>>[2],
]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== parseTextNoteContent / nevent payload =="
fd -i 'text-note-content.ts' src -x sed -n '1,220p' {}

echo
echo "== query helper relay plumbing =="
fd -i 'query-helpers.ts' src -x sed -n '1,200p' {}

echo
echo "== decoded nevent relay usage =="
rg -n -C2 --type=ts --type=tsx 'decoded\.(relay|relays)|\bnevent\b' src

Repository: mouse484/astraea

Length of output: 4591


🏁 Script executed:

# First, find the createEvent implementation to understand what nevent decode returns
fd -i 'nip19' src -type f

Repository: mouse484/astraea

Length of output: 230


🏁 Script executed:

# Search for NostrEvent.tsx to see how it's using decoded events
fd -i 'NostrEvent.tsx' src -type f

Repository: mouse484/astraea

Length of output: 230


🏁 Script executed:

# Better search for nevent relay usage without the problematic tsx flag
rg -n 'nevent.*relay|relays.*nevent' src --type ts

Repository: mouse484/astraea

Length of output: 155


🏁 Script executed:

# Look for how createEvent is being used with relays
rg -n -C3 'createEvent' src --type ts --type tsx

Repository: mouse484/astraea

Length of output: 87


🏁 Script executed:

# Fix the fd command - use correct syntax
find src -name '*nip19*' -type f

Repository: mouse484/astraea

Length of output: 82


🏁 Script executed:

# Find and examine NostrEvent.tsx
find src -name 'NostrEvent.tsx' -type f

Repository: mouse484/astraea

Length of output: 89


🏁 Script executed:

# Look at the nevent route that uses decoded.relays
cat src/routes/\(app\)/\(textnote\)/nevent1\{\$id\}.tsx

Repository: mouse484/astraea

Length of output: 1706


🏁 Script executed:

# Examine NostrEvent.tsx, especially the lines mentioned in the review (8-11 and 15-23)
cat -n src/components/NostrEvent.tsx | head -40

Repository: mouse484/astraea

Length of output: 1112


🏁 Script executed:

# Look at the createEvent implementation in nip19.ts
cat -n src/lib/nostr/nip19.ts

Repository: mouse484/astraea

Length of output: 2673


🏁 Script executed:

# Search for usage of NostrEvent component to see if it's being used with decoded nevents
rg -n 'NostrEvent' src --type-add 'tsx:*.tsx' -t tsx

Repository: mouse484/astraea

Length of output: 1142


🏁 Script executed:

# Check if there are any inline nevent decoding with relays being used with NostrEvent
rg -n -B5 -A5 'decoded.*relays|NostrEvent.*nevent' src --type-add 'tsx:*.tsx' -t tsx

Repository: mouse484/astraea

Length of output: 981


🏁 Script executed:

# Look at TextNoteContent.tsx to see how it's using NostrEvent with decoded content
cat -n src/components/text-note/TextNoteContent.tsx

Repository: mouse484/astraea

Length of output: 1597


🏁 Script executed:

# Check the useNostr hook to understand what queryContext provides
find src -name 'use-nostr*' -type f

Repository: mouse484/astraea

Length of output: 132


🏁 Script executed:

# Check if relays parameter in queryFunction is actually used
cat -n src/lib/nostr/query-helpers.ts | head -80

Repository: mouse484/astraea

Length of output: 3194


🏁 Script executed:

# Examine useNostr hook to see what it provides
cat -n src/lib/nostr/hooks/use-nostr.ts

Repository: mouse484/astraea

Length of output: 1515


🏁 Script executed:

# Check if nevent decoded data actually includes relays field
rg -n 'decoded\.relays' src

Repository: mouse484/astraea

Length of output: 155


Add mechanism to pass relay hints through NostrEvent component.

The decoded nevent payload exposes relay hints via .decoded.relays (confirmed in route handlers), and the query function properly uses them when available in context.relays (line 63-64 in query-helpers.ts). However, TextNoteContent.tsx parses nevent identifiers with relays but cannot pass them through the NostrEvent component—queryOptions only carries [id, setQueryKeyFunction], while useNostr() provides no relay context. This leaves embedded note references unable to leverage their hinted relays.

Consider either expanding queryOptions to include optional relays, or adding a context-shaping callback to preserve this path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/NostrEvent.tsx` around lines 8 - 11, The NostrEvent component
currently cannot forward relay hints because queryOptions only carries [id,
setQueryKeyFunction] and useNostr() has no relay context; update the shape of
queryOptions to optionally include relays (e.g. queryOptions: readonly [string,
Parameters<QueryFunction<T>>[2], { relays?: string[] }?]) or add a
context-shaping callback prop on NostrEvent that returns { relays } from the
parsed nevent; then update NostrEvent to accept and pass that relays object into
useNostr()/the query context and update callers (TextNoteContent.tsx) to supply
the parsed nevent.decoded.relays into NostrEvent so the existing query helper
(queryFunction in query-helpers.ts which reads context.relays) can use the
hinted relays.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant