akiomik / akiomik/nosvelte

A refetch reuses the same rxReqId, so its REQ is silently dropped

Open
#94 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
TypeScript
Stars
29
Forks
3
Avg merge
3h 5m
Merged PRs (30d)
11

Description

`useReq()` creates its req once, when the hook is called
(`src/lib/stores/useReq.ts:37`), and builds one observable from it
(`:42`). Every fetch attempt then re-subscribes that same observable.

rx-nostr derives the wire subId as `` `${rxReqId}:${index}` `` where `index` is a
*per-subscription* counter that restarts at 0
(`rx-nostr/utils.ts:11-18`, `rx-nostr.ts:353-357`). A req object carries one
`rxReqId` for its whole life (`rx-req.ts:125`), so **every attempt sends the
identical subId**.

For a backward/oneshot req `use()` passes `overwrite: false`, and the connection
drops a REQ whose subId is already in flight
(`connection/connection.ts:181`):

```ts
if (!overwrite && this.subProxy.isOngoingOrQueued(subId)) return;
```

So a refetch that starts while the previous subscription is still open never
reaches the relay at all.

Verified on `main` (609f8ed) against the mock relay: a list hook received one
event, was refetched before EOSE, and the relay saw a single message for the
whole test —

```
WIRE: [["REQ","408976:0",{"kinds":[1]}]]
```

The refetch produced no REQ, no error, and no change in status. The query
resubscribes an operator chain that is fed by a subscription the relay is no
longer being asked to serve.

This is a different defect from #82, which is about the accumulator restarting
from its seed. Both fire on the same refetch, and #82's report notes the missing
second REQ as a symptom; this issue is the cause of that half.

## Interaction with a caller-supplied forward req

A forward req uses `overwrite: true`, so the duplicate is not dropped — the new
REQ replaces the old one on the wire while **both** RxJS chains keep filtering on
the same subId. Combined with #61 (the previous subscription is never torn down)
that means two live chains writing different accumulations to one cache key.

## Direction

Mint a fresh req — and therefore a fresh subId — per fetch attempt rather than
per hook call. Passing an explicit `rxReqId` to the factory is enough; all three
factories accept one (`rx-req.ts:164`, `:188`, `:204-207`).

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in src/lib/stores/useReq.ts at req creation and observable construction, then read the rx-req.ts factories and rx-nostr.ts subId generation. Check the mock-relay refetch scenario described in the issue; done means each fetch attempt reaches the relay with a distinct REQ subId instead of being silently dropped.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.