Skip to content

fix: FDv2 - Support dynamic reconnect URL for streaming. Handle 'error' event types for SSE.#1252

Merged
kinyoklion merged 2 commits into
mainfrom
rlamb/fdv2-contract-test-updates
Apr 9, 2026
Merged

fix: FDv2 - Support dynamic reconnect URL for streaming. Handle 'error' event types for SSE.#1252
kinyoklion merged 2 commits into
mainfrom
rlamb/fdv2-contract-test-updates

Conversation

@kinyoklion

@kinyoklion kinyoklion commented Apr 7, 2026

Copy link
Copy Markdown
Member

Note

Medium Risk
Changes streaming reconnection behavior and browser SSE error handling, which could affect connection stability and update delivery if the new URL-building or error classification is incorrect. Scope is limited to streaming/EventSource plumbing plus contract-test config tweaks.

Overview
Improves FDv2 streaming reconnect behavior by adding an optional urlBuilder to EventSourceInitDict and wiring FDv2 streaming to rebuild the stream URL (including dynamic query params like basis) on each reconnect attempt.

Updates the browser DefaultBrowserEventSource to use urlBuilder when reopening connections and to ignore server-sent SSE event: error messages in onerror (treating them as non-connection failures).

Contract-test tooling is adjusted to better support Data System configs without explicit connection modes (wrapping top-level initializers/synchronizers into a single streaming mode), plus minor repo hygiene (.mcp.json ignored; adds start:headless script).

Reviewed by Cursor Bugbot for commit fdf83b0. Bugbot is set up for automated code reviews on this repo. Configure here.

- Add start:headless script for running contract test entity without
  auto-opening a browser window
- Handle top-level dataSystem initializers/synchronizers in the contract
  test entity by wrapping them into a streaming connection mode
- Fix browser EventSource onerror firing for server-sent "error" SSE
  events by checking for MessageEvent instances
- Add urlBuilder to EventSourceInitDict so the browser EventSource can
  refresh the URL (including basis param) on reconnection
- Pass buildStreamUri as urlBuilder in StreamingFDv2Base
@github-actions

github-actions Bot commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

@launchdarkly/js-sdk-common size report
This is the brotli compressed size of the ESM build.
Compressed size: 25661 bytes
Compressed size limit: 29000
Uncompressed size: 126143 bytes

"scripts": {
"install-playwright-browsers": "playwright install --with-deps chromium",
"start": "tsc --noEmit && vite --open=true",
"start:headless": "tsc --noEmit && vite",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Helper for LLMs to run contract tests.

@github-actions

github-actions Bot commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

@launchdarkly/browser size report
This is the brotli compressed size of the ESM build.
Compressed size: 179348 bytes
Compressed size limit: 200000
Uncompressed size: 830127 bytes

@github-actions

github-actions Bot commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

@launchdarkly/js-client-sdk size report
This is the brotli compressed size of the ESM build.
Compressed size: 31736 bytes
Compressed size limit: 34000
Uncompressed size: 112937 bytes

@github-actions

github-actions Bot commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

@launchdarkly/js-client-sdk-common size report
This is the brotli compressed size of the ESM build.
Compressed size: 37181 bytes
Compressed size limit: 38000
Uncompressed size: 204409 bytes

@kinyoklion

Copy link
Copy Markdown
Member Author

Change Summary

This PR fixes the browser SDK to pass FDv2 contract tests. Here's what each change does:

.gitignore

Adds .mcp.json to gitignore — this is a local MCP server configuration file that shouldn't be checked in.

packages/sdk/browser/contract-tests/entity/package.json

Adds a start:headless script that runs the Vite dev server without --open=true. This prevents a second browser window from auto-opening when running contract tests via Chrome DevTools MCP or other headless approaches.

packages/sdk/browser/contract-tests/entity/src/ClientEntity.ts

Two changes:

  1. Extracted applyEndpointOverrides helper — refactors the endpoint URI extraction logic (previously inline in the connectionModeConfig branch) into a reusable function.
  2. Added support for top-level dataSystem.initializers/synchronizers — Some FDv2 contract tests send initializers and synchronizers at the top level of dataSystem (without connectionModeConfig). The browser SDK requires connection modes, so the entity now wraps top-level initializers/synchronizers into a single 'streaming' connection mode. This fixes the polling initializer tests (e.g. "initializes from polling initializer") and the multi-synchronizer tests (e.g. "disconnects on goodbye").

packages/sdk/browser/src/platform/DefaultBrowserEventSource.ts

Two fixes:

  1. instanceof MessageEvent guard in onerror — In Chrome, when the server sends an SSE event with event: error, the native EventSource fires BOTH addEventListener('error', ...) AND onerror. The onerror handler was unconditionally closing the connection and reconnecting, which prevented the FDv2 protocol handler from processing server-sent error events. A server-sent error arrives as a MessageEvent, while a real connection error is a plain Event — so we skip _handleError for MessageEvent instances.
  2. urlBuilder support for reconnection — The browser's native EventSource reconnects to the same URL. For FDv2, the basis query parameter needs to be updated on each reconnection to reflect the most recently received selector/state. The _openConnection method now calls urlBuilder() (if provided) to get a fresh URL before creating a new EventSource.

packages/shared/common/src/api/platform/EventSource.ts

Adds an optional urlBuilder callback to EventSourceInitDict. Platform EventSource implementations can call this on reconnection to get an updated URL (e.g. with a refreshed basis query parameter).

packages/shared/sdk-client/src/datasource/fdv2/StreamingFDv2Base.ts

Passes buildStreamUri as the urlBuilder when creating the EventSource. This ensures that when the browser EventSource reconnects, it calls buildStreamUri() which reads the current selector via selectorGetter() and includes the correct basis parameter.

@kinyoklion kinyoklion changed the title fix: Fixes for browser FDv2 contract tests. fix: FDv2 - Support dynamic reconnect URL for streaming. Handle 'error' event types for SSE. Apr 7, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The jank in here may be temporary as @tanderson-ld and @aaron-zeisler are adjusting the tests.

@kinyoklion

Copy link
Copy Markdown
Member Author

bugbot review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit fdf83b0. Configure here.

@kinyoklion kinyoklion marked this pull request as ready for review April 7, 2026 22:21
@kinyoklion kinyoklion requested a review from a team as a code owner April 7, 2026 22:21
@kinyoklion kinyoklion merged commit 4ef6cdd into main Apr 9, 2026
43 checks passed
@kinyoklion kinyoklion deleted the rlamb/fdv2-contract-test-updates branch April 9, 2026 16:07
@github-actions github-actions Bot mentioned this pull request Apr 8, 2026
joker23 pushed a commit that referenced this pull request Apr 14, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>akamai-edgeworker-sdk-common: 2.0.18</summary>

##
[2.0.18](akamai-edgeworker-sdk-common-v2.0.17...akamai-edgeworker-sdk-common-v2.0.18)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/js-server-sdk-common bumped from ^2.18.3 to ^2.18.4
</details>

<details><summary>akamai-server-base-sdk: 3.0.19</summary>

##
[3.0.19](akamai-server-base-sdk-v3.0.18...akamai-server-base-sdk-v3.0.19)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
* @launchdarkly/akamai-edgeworker-sdk-common bumped from ^2.0.17 to
^2.0.18
    * @launchdarkly/js-server-sdk-common bumped from ^2.18.3 to ^2.18.4
</details>

<details><summary>akamai-server-edgekv-sdk: 1.4.21</summary>

##
[1.4.21](akamai-server-edgekv-sdk-v1.4.20...akamai-server-edgekv-sdk-v1.4.21)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
* @launchdarkly/akamai-edgeworker-sdk-common bumped from ^2.0.17 to
^2.0.18
    * @launchdarkly/js-server-sdk-common bumped from ^2.18.3 to ^2.18.4
</details>

<details><summary>browser: 0.1.14</summary>

##
[0.1.14](browser-v0.1.13...browser-v0.1.14)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/js-client-sdk bumped from 4.4.1 to 4.5.0
</details>

<details><summary>browser-telemetry: 1.0.30</summary>

##
[1.0.30](browser-telemetry-v1.0.29...browser-telemetry-v1.0.30)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @launchdarkly/js-client-sdk bumped from 4.4.1 to 4.5.0
</details>

<details><summary>cloudflare-server-sdk: 2.7.18</summary>

##
[2.7.18](cloudflare-server-sdk-v2.7.17...cloudflare-server-sdk-v2.7.18)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
* @launchdarkly/js-server-sdk-common-edge bumped from 2.6.16 to 2.6.17
</details>

<details><summary>fastly-server-sdk: 0.2.10</summary>

##
[0.2.10](fastly-server-sdk-v0.2.9...fastly-server-sdk-v0.2.10)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/js-server-sdk-common bumped from 2.18.3 to 2.18.4
</details>

<details><summary>jest: 1.0.9</summary>

##
[1.0.9](jest-v1.0.8...jest-v1.0.9)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
* @launchdarkly/react-native-client-sdk bumped from ~10.15.1 to ~10.15.2
</details>

<details><summary>js-client-sdk: 4.5.0</summary>

##
[4.5.0](js-client-sdk-v4.4.1...js-client-sdk-v4.5.0)
(2026-04-14)


### Features

* add retry logic to FDv2 polling initializer
([#1230](#1230))
([fe8bd37](fe8bd37))
* expose setConnectionMode on browser SDK
([#1232](#1232))
([9019808](9019808))
* FDv2 contract test wiring, suppressions, and example app, cleanup
configuration exports.
([#1225](#1225))
([c67c5f6](c67c5f6))
* wire FDv2 data manager into BrowserClient
([#1222](#1222))
([0b855f0](0b855f0))


### Bug Fixes

* FDv2 - Support dynamic reconnect URL for streaming. Handle 'error'
event types for SSE.
([#1252](#1252))
([4ef6cdd](4ef6cdd))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/js-client-sdk-common bumped from 1.23.0 to 1.24.0
</details>

<details><summary>js-client-sdk-common: 1.24.0</summary>

##
[1.24.0](js-client-sdk-common-v1.23.0...js-client-sdk-common-v1.24.0)
(2026-04-14)


### Features

* add retry logic to FDv2 polling initializer
([#1230](#1230))
([fe8bd37](fe8bd37))
* expose setConnectionMode on browser SDK
([#1232](#1232))
([9019808](9019808))
* FDv2 contract test wiring, suppressions, and example app, cleanup
configuration exports.
([#1225](#1225))
([c67c5f6](c67c5f6))
* FDv2DataManagerBase for mode switching and data source lifecycle
([#1210](#1210))
([8f8051c](8f8051c))
* support per-mode FDv1 fallback configuration
([#1246](#1246))
([9956bce](9956bce))
* wire FDv2 data manager into BrowserClient
([#1222](#1222))
([0b855f0](0b855f0))


### Bug Fixes

* FDv2 - Support dynamic reconnect URL for streaming. Handle 'error'
event types for SSE.
([#1252](#1252))
([4ef6cdd](4ef6cdd))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/js-sdk-common bumped from 2.24.0 to 2.24.1
</details>

<details><summary>js-sdk-common: 2.24.1</summary>

##
[2.24.1](js-sdk-common-v2.24.0...js-sdk-common-v2.24.1)
(2026-04-14)


### Bug Fixes

* FDv2 - Support dynamic reconnect URL for streaming. Handle 'error'
event types for SSE.
([#1252](#1252))
([4ef6cdd](4ef6cdd))
</details>

<details><summary>js-server-sdk-common: 2.18.4</summary>

##
[2.18.4](js-server-sdk-common-v2.18.3...js-server-sdk-common-v2.18.4)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/js-sdk-common bumped from 2.24.0 to 2.24.1
</details>

<details><summary>js-server-sdk-common-edge: 2.6.17</summary>

##
[2.6.17](js-server-sdk-common-edge-v2.6.16...js-server-sdk-common-edge-v2.6.17)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/js-server-sdk-common bumped from 2.18.3 to 2.18.4
</details>

<details><summary>node-server-sdk: 9.10.11</summary>

##
[9.10.11](node-server-sdk-v9.10.10...node-server-sdk-v9.10.11)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/js-server-sdk-common bumped from 2.18.3 to 2.18.4
</details>

<details><summary>node-server-sdk-dynamodb: 6.2.23</summary>

##
[6.2.23](node-server-sdk-dynamodb-v6.2.22...node-server-sdk-dynamodb-v6.2.23)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @launchdarkly/node-server-sdk bumped from 9.10.10 to 9.10.11
  * peerDependencies
    * @launchdarkly/node-server-sdk bumped from >=9.4.3 to >=9.10.11
</details>

<details><summary>node-server-sdk-otel: 1.3.11</summary>

##
[1.3.11](node-server-sdk-otel-v1.3.10...node-server-sdk-otel-v1.3.11)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @launchdarkly/node-server-sdk bumped from 9.10.10 to 9.10.11
  * peerDependencies
    * @launchdarkly/node-server-sdk bumped from >=9.4.3 to >=9.10.11
</details>

<details><summary>node-server-sdk-redis: 4.2.23</summary>

##
[4.2.23](node-server-sdk-redis-v4.2.22...node-server-sdk-redis-v4.2.23)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @launchdarkly/node-server-sdk bumped from 9.10.10 to 9.10.11
  * peerDependencies
    * @launchdarkly/node-server-sdk bumped from >=9.4.3 to >=9.10.11
</details>

<details><summary>react-native-client-sdk: 10.15.2</summary>

##
[10.15.2](react-native-client-sdk-v10.15.1...react-native-client-sdk-v10.15.2)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/js-client-sdk-common bumped from 1.23.0 to 1.24.0
</details>

<details><summary>react-sdk: 0.2.0</summary>

##
[0.2.0](react-sdk-v0.1.1...react-sdk-v0.2.0)
(2026-04-14)


### Features

* adding isomorphic provider to bridge client and server
([#1218](#1218))
([d766f39](d766f39))
* support static client component rendering
([#1227](#1227))
([6b3a100](6b3a100))


### Bug Fixes

* adding wrapper name for react client
([#1199](#1199))
([f92a8f9](f92a8f9))
* **deps:** update dependency next to v16.2.3 [security]
([#1263](#1263))
([10f582a](10f582a))
* **react-sdk:** double evaluation on client side init
([#1229](#1229))
([6a4c42f](6a4c42f))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/js-client-sdk bumped from ^4.4.1 to ^4.5.0
    * @launchdarkly/js-server-sdk-common bumped from ^2.18.3 to ^2.18.4
</details>

<details><summary>server-sdk-ai: 0.16.8</summary>

##
[0.16.8](server-sdk-ai-v0.16.7...server-sdk-ai-v0.16.8)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @launchdarkly/js-server-sdk-common bumped from 2.18.3 to 2.18.4
  * peerDependencies
    * @launchdarkly/js-server-sdk-common bumped from 2.x to 2.18.4
</details>

<details><summary>server-sdk-ai-langchain: 0.5.4</summary>

##
[0.5.4](server-sdk-ai-langchain-v0.5.3...server-sdk-ai-langchain-v0.5.4)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @launchdarkly/server-sdk-ai bumped from ^0.16.7 to ^0.16.8
  * peerDependencies
* @launchdarkly/server-sdk-ai bumped from ^0.15.0 || ^0.16.0 to ^0.16.8
</details>

<details><summary>server-sdk-ai-openai: 0.5.4</summary>

##
[0.5.4](server-sdk-ai-openai-v0.5.3...server-sdk-ai-openai-v0.5.4)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @launchdarkly/js-server-sdk-common bumped from 2.18.3 to 2.18.4
    * @launchdarkly/server-sdk-ai bumped from ^0.16.7 to ^0.16.8
  * peerDependencies
* @launchdarkly/server-sdk-ai bumped from ^0.15.0 || ^0.16.0 to ^0.16.8
</details>

<details><summary>server-sdk-ai-vercel: 0.5.4</summary>

##
[0.5.4](server-sdk-ai-vercel-v0.5.3...server-sdk-ai-vercel-v0.5.4)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @launchdarkly/server-sdk-ai bumped from ^0.16.7 to ^0.16.8
  * peerDependencies
* @launchdarkly/server-sdk-ai bumped from ^0.15.0 || ^0.16.0 to ^0.16.8
</details>

<details><summary>shopify-oxygen-sdk: 0.1.8</summary>

##
[0.1.8](shopify-oxygen-sdk-v0.1.7...shopify-oxygen-sdk-v0.1.8)
(2026-04-14)


### Bug Fixes

* **shopify:** standardizing the pre-release banner
([#1268](#1268))
([82adddb](82adddb))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/js-server-sdk-common bumped from 2.18.3 to 2.18.4
</details>

<details><summary>vercel-server-sdk: 1.3.43</summary>

##
[1.3.43](vercel-server-sdk-v1.3.42...vercel-server-sdk-v1.3.43)
(2026-04-14)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
* @launchdarkly/js-server-sdk-common-edge bumped from 2.6.16 to 2.6.17
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Primarily automated version/changelog updates across many packages;
the only functional change in-code is updating embedded SDK/version
identifiers, which is low risk but could affect user-agent/wrapper
reporting.
> 
> **Overview**
> Bumps versions and publishes release metadata across the monorepo
(manifest, `package.json`s, and changelogs), including `js-client-sdk`
`4.5.0`, `react-sdk` `0.2.0`, and multiple server/edge/provider
packages.
> 
> Updates embedded `x-release-please-version` constants used for SDK
identification (e.g., `BrowserInfo`, `NodeInfo`, edge platform info) and
updates the React client default `wrapperVersion` to `0.2.0` for
telemetry/user-agent reporting.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a09a298. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

2 participants