akiomik / akiomik/nosvelte

Every req takes rx-nostr's random rxReqId, so concurrent hooks can collide

Open
#95 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()` never passes an `rxReqId`, so every req falls back to rx-nostr's
default (`rx-req.ts:125, 220-222`):

```ts
rxReqId: params.rxReqId ?? getRandomDigitsString()
// `${Math.floor(Math.random() * 1_000_000)}`
```

That is a 10^6 space shared by every concurrent request in the page. Two hooks
that happen to draw the same number produce the same wire subId, and rx-nostr
then either drops one of them silently (backward: `connection.ts:181`) or lets
them overwrite each other and cross-talk (forward: `rx-nostr.ts:325`).

By the birthday bound the probability of at least one collision among `n`
concurrent reqs is roughly `1 - exp(-n^2 / 2e6)`: about 0.5% at 100, 12% at 500,
39% at 1000. A feed that renders a `` and a `` per item reaches
those counts on a long timeline — `src/routes/timeline/+page.svelte` and
`src/routes/n-plus-1/+page.svelte` both fan out this way.

The symptom when it happens is a hook that stays `'loading'` forever, or one
that receives another hook's events, with nothing in the logs.

Determined by code reading; not reproduced (it is probabilistic by nature).
The id in a captured wire log from an unrelated test — `["REQ","408976:0",...]`
— shows the default is in use.

## Direction

Pass an explicit `rxReqId` from a per-context counter. This removes the failure
mode entirely rather than making it rarer, and it costs nothing: all three
factories already accept one (`rx-req.ts:164`, `:188`, `:204-207`).

Related: #61 and #82 both concern the same req being reused; this one is about
distinct reqs colliding.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start at useReq() and trace the rxReqId handling in rx-req.ts, then inspect the per-context call sites in src/routes/timeline/+page.svelte and src/routes/n-plus-1/+page.svelte. Use the backward and forward paths named in connection.ts and rx-nostr.ts to understand the collision behavior. Done means concurrent hooks receive distinct explicit request IDs instead of the shared random fallback.

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.