Repository navigation
fix(react): build @streamfi/react again — 20 type errors, 40 failing tests - #1039
arkhindi12 wants to merge 1 commit into
Conversation
…tests `@streamfi/react` has never passed CI: the job is gated on `needs: [build]`, and `build` has been skipped on every run since main stopped typechecking, so these errors were never surfaced. Now that conduit-protocol#1038 unblocks the chain, the package fails 20 type errors across 10 files and 40 of its 102 tests. Typecheck: 20 errors -> 0 Tests: 40 failed / 62 passed -> 0 failed / 111 passed `StreamFiProvider` — `rpcHeaders` was never implemented ------------------------------------------------------- conduit-protocol#1009 (`a9d49a2`) added a call site without the feature: ```tsx const customFetch = rpcHeaders && Object.keys(rpcHeaders).length > 0 ? makeHeaderFetch(rpcHeaders) : undefined; ``` Neither name existed. `rpcHeaders` is not a member of `StreamFiProviderProps` (only `config`, `defaultNetwork`, `children`, `queryClient`), and `makeHeaderFetch` appears nowhere in the repository — `git log -S` finds only that one commit. The feature was merged as a use of things that were never added, so the package could not compile and `rpcHeaders` did nothing. Implemented the intended behaviour rather than deleting the call site, since `ConduitConfig.customFetch` is already the documented hook for exactly this ("request-tracing headers"): * `makeHeaderFetch(headers, baseFetch?)` wraps `fetch` and merges `headers` into each request. A header set per request wins; `Headers` handles the case-insensitive merge. `undefined` values are skipped — `Headers` would otherwise stringify them into the literal `"undefined"`. * `RpcHeaders = Record<string, string | undefined>` exported from the package. * `rpcHeaders` added to `StreamFiProviderProps` and destructured, memoised on the prop so a new wrapper is not registered on every render (`registerCustomFetch` is keyed by `rpcUrl` and would be overwritten). Covered by 9 new tests: header injection, caller-wins precedence, `Headers` and tuple init forms, `undefined` values, omitted `init`, and three provider cases (headers forwarded, no headers, empty object). `rootDir` violations -------------------- `useCircuitState` and `useTransactionHistory` imported across the package boundary into the SDK's source tree (`../../../../src/...`), which `tsc` refuses to emit outside `rootDir`. They now import the package's public surface: `@conduit-protocol/sdk` and `@conduit-protocol/sdk/dashboard`. The circuit test had the same import, which mattered beyond `rootDir`: the hook resolved the package (→ `dist/`) while the test resolved `src/`, creating two separate circuit registries, so `recordFailure` never affected the state the hook read. Aligned the test with the hook. Stale SDK signatures -------------------- * `useStreamsByRecipient` / `useStreamsBySender` treated `factory.streamsBySender()` as `bigint[]`; it returns `{ ids, hasMore }`. They also re-derived `hasMore` from `ids.length === limit` while the SDK already computes it against the *clamped* limit — now uses the SDK's value. * `useCancelStream`: `CancelStreamFn` claimed `Promise<string>`, but the documented behaviour is "opens the in-app confirmation flow; does not contact the wallet", and both paths return `undefined`. Corrected to `Promise<void>`; `confirmCancel` remains the call that yields a hash. Smaller fixes ------------- * `useTransferStreamRecipient`: `useState` used but not imported. * `useGovernorConfig` / `useGovernorProposals`: optional result and option fields did not admit `undefined` under `exactOptionalPropertyTypes`. * `useTransactionHistory`: `walletAddress: undefined` spread conditionally instead of passed explicitly. * `useStreamNotes`: `noUncheckedIndexedAccess` — guard the key/value pair before indexing. Test fixes ---------- * Seven files mocked `@conduit-protocol/sdk` with only `ConduitClient`, so every render threw "No SUPPORTED_NETWORKS export". The mocks now stub what `StreamFiProvider` reads at module scope. * `useStreamCountdown`: the hook polls on `requestAnimationFrame`, and jsdom quantises frames to ~16.67ms, so `advanceTimersByTime(1000)` lands at ~983ms — one frame short of the boundary. Advancing by a frame extra makes the tests exercise the hook rather than the frame scheduler; the two `progressFraction` equality checks became `toBeCloseTo`. * `issue-989`: the test awaited `resume()` against a never-resolving `get`, but `resume()` settles only after the post-submit refresh. It asserts submission, so it now waits for the mutation call instead of the promise. Verified: `tsc --noEmit` clean, 111/111 tests, `tsup` build succeeds. SDK suite still 1643/1643 and typechecks clean.
Cross-PR verification: both green togetherThe two PRs are mutually blocking in CI, so neither can prove the other:
To prove they are green together rather than just locally, I built a throwaway branch on top of 7/7 pass, including the Local state on that combined branch: Merge order
The two branches touch disjoint files ( I am closing the temporary verification PR now; it contains no changes of its own. |
@streamfi/reacthas never passed CI. The job is gated onneeds: [build], andbuildhas been skipped on every run sincemainstopped typechecking — so these errors were never surfaced. Now that #1038 unblocks the chain, the package fails 20 type errors across 10 files and 40 of its 102 tests.StreamFiProvider—rpcHeaderswas never implemented#1009 (
a9d49a2) added a call site without the feature:Neither name existed:
That single hit is the added use of
makeHeaderFetch— the commit never added the helper, andrpcHeadersis not a member ofStreamFiProviderProps(which has onlyconfig,defaultNetwork,children,queryClient). So the header-forwarding feature was merged as a reference to two things that do not exist: the package could not compile, andrpcHeaderscould not have done anything.I implemented the intended behaviour rather than deleting the call site, because
ConduitConfig.customFetchis already documented as the hook for exactly this — "for edge runtimes (Cloudflare Workers), proxies/custom HTTP agents, request-tracing headers, or timeouts that the globalfetchdoes not provide":makeHeaderFetch(headers, baseFetch?)wrapsfetchand mergesheadersinto each request. A header set per request wins;Headershandles the case-insensitive merge.undefinedvalues are skipped —Headerswould otherwise stringify them into the literal"undefined".RpcHeaders = Record<string, string | undefined>, exported.rpcHeadersadded toStreamFiProviderPropsand destructured, memoised on the prop so a fresh wrapper is not registered on every render (registerCustomFetchis keyed byrpcUrland would be overwritten constantly).An empty object or absent prop leaves
customFetchundefined, so the SDK keeps using the platformfetch.Covered by 9 new tests: header injection, caller-wins precedence,
Headersand tuple-array init forms,undefinedvalues, omittedinit, plus three provider cases (headers forwarded to the constructed client, no prop, empty object).rootDirviolationsuseCircuitStateanduseTransactionHistoryreached across the package boundary into the SDK's source tree (../../../../src/...), whichtscrefuses to emit outsiderootDir. They now import the public surface:@conduit-protocol/sdkand@conduit-protocol/sdk/dashboard.The circuit test had the same import, and that mattered beyond
rootDir: the hook resolved the package (→dist/) while the test resolvedsrc/, producing two separate circuit registries.recordFailurein the test never affected the state the hook read, so those assertions could not pass. The test now imports what the hook imports.Stale SDK signatures
useStreamsByRecipient/useStreamsBySendertreatedfactory.streamsBySender()asbigint[]; it returns{ ids, hasMore }. They also re-derivedhasMorefromids.length === limit, while the SDK already computes it against the clamped limit — they now use the SDK's value, which is correct whenlimitis out of range.useCancelStream—CancelStreamFnclaimedPromise<string>, but the documented behaviour is "Opens the in-app confirmation flow; does not contact the wallet", and both return paths yieldundefined. Corrected toPromise<void>;confirmCancelis the call that produces a hash. No test asserted a hash fromcancel.Smaller fixes
useTransferStreamRecipient:useStateused but never imported.useGovernorConfig/useGovernorProposals: optional result and option fields did not admitundefinedunderexactOptionalPropertyTypes; the implementation overload now matches the second public overload.useTransactionHistory:walletAddressspread conditionally instead of passed asundefined.useStreamNotes:noUncheckedIndexedAccess— guard the key/value pair before using it as an index.Test fixes
Four of these were tests asserting something the code never promised:
@conduit-protocol/sdkwith onlyConduitClient, so every render threwNo "SUPPORTED_NETWORKS" export is defined on the "@conduit-protocol/sdk" mock. The mocks now stub whatStreamFiProviderreads at module scope. (useNetworkSwitcheranduseWithdrawableAmountalready spreadimportActual/importOriginaland were fine.)useStreamCountdown— the hook polls the clock onrequestAnimationFrame, and jsdom quantises frames to ~16.67ms, soadvanceTimersByTime(1000)stops at ~983ms, one frame short of the second boundary. Verified directly: advancing 1016ms ticks, 1000ms does not. Advancing one frame past the boundary makes the tests exercise the hook rather than the frame scheduler; the twoprogressFractionequality checks becametoBeCloseTo.issue-989— the test awaitedresume()whilegetwas a never-resolving promise, butresume()settles only after the post-submit refresh. The assertion is that the transaction is submitted, so it now waits for the mutation call rather than the promise.Verification
The SDK suite is unchanged by this PR —
git diff --name-only main...HEADtouches onlypackages/react/.