Conversation
|
@launchdarkly/js-sdk-common size report |
|
@launchdarkly/browser size report |
|
@launchdarkly/js-client-sdk size report |
|
@launchdarkly/js-client-sdk-common size report |
| <ClientInner | ||
| clientId={id} | ||
| handlers={commandHandlers.current} | ||
| onReady={(readyId) => handlerReadyMap.current.get(readyId)?.()} |
There was a problem hiding this comment.
Unstable onReady callback causes effect re-runs and handler gaps
Medium Severity
The onReady prop is an inline arrow function (readyId) => handlerReadyMap.current.get(readyId)?.() that creates a new reference on every render. Since ClientInner's useEffect lists onReady as a dependency, the effect re-runs on every parent re-render. Each re-run first executes cleanup (deleting the command handler from the map), then re-registers it. This creates a brief window where no handler exists for that client. When a new client is added via setClients, all existing ClientInner components re-render, causing all their handlers to be momentarily removed — any runCommand arriving during that gap gets a 404 response. The onReady callback needs to be stabilized (e.g., via useCallback).
Additional Locations (1)
| record.client.close(); | ||
| } | ||
| return prev.filter((r) => r.id !== id); | ||
| }); |
There was a problem hiding this comment.
Side effect in React state updater may execute multiple times
Low Severity
The _onDeleteClient callback calls record.client.close() inside a setClients state updater function. React state updaters are expected to be pure — React may invoke them more than once (e.g., in StrictMode or concurrent rendering), which would call close() on the same client multiple times. The close() call is a side effect that belongs outside the updater.
28e9506 to
88315e6
Compare
| setTimeout(() => { | ||
| this.connect(); | ||
| }, 1000); | ||
| }; |
There was a problem hiding this comment.
WebSocket reconnects after intentional disconnect in StrictMode
Medium Severity
The onclose handler unconditionally schedules a reconnect via setTimeout. When layout.tsx's useEffect cleanup calls ws.disconnect(), this triggers onclose, which schedules a reconnect after 1 second. Under React StrictMode (active in Next.js dev mode), the effect mounts, unmounts, and remounts — creating a second TestHarnessWebSocket instance. The first instance also reconnects 1 second later, resulting in two active WebSocket connections processing commands in parallel and sending duplicate responses.
Additional Locations (1)
88315e6 to
fd066db
Compare
f582c85 to
50833ff
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
50833ff to
9d0544a
Compare
8dcb7b8 to
0c9f3f2
Compare
080fdde to
28d9696
Compare
28d9696 to
a16497c
Compare


This PR will add the initial contract tests for react sdk
Current limitation of the contract tests is that they are basically just testing the underlying browser sdk. We will iterate these tests to be more idiomatic to the react SDK.
Note
Medium Risk
Primarily adds CI/test-only infrastructure, but it also introduces a new Next.js/Playwright workspace and updates React type dependencies, which could affect installs/CI stability and TypeScript checks.
Overview
Adds an initial contract-test implementation for
@launchdarkly/react-sdkby introducing a newpackages/sdk/react/contract-testsworkspace that spins up the existing browser adapter, a Next.js “entity” app, and a headless Playwright browser to execute SDK Test Harness commands over WebSocket.Updates
sdk/reactCI (react.yaml) to install/build the new workspaces, install Playwright browsers, start the local test services, and run the sharedcontract-testsGitHub Action with a suppressions list. Also adds React package lint config overrides for the contract-test TS project and bumps@types/react/adds@types/react-domin the React SDK dev deps.Written by Cursor Bugbot for commit 9d0544a. This will update automatically on new commits. Configure here.