Skip to content

feat: Add FDv2 streaming source factories and query-parameter authentication#306

Merged
kinyoklion merged 1 commit into
rlamb/sdk-2186/fdv2-source-translationfrom
rlamb/sdk-2186/fdv2-streaming-source
Jun 15, 2026
Merged

feat: Add FDv2 streaming source factories and query-parameter authentication#306
kinyoklion merged 1 commit into
rlamb/sdk-2186/fdv2-source-translationfrom
rlamb/sdk-2186/fdv2-streaming-source

Conversation

@kinyoklion

@kinyoklion kinyoklion commented Jun 12, 2026

Copy link
Copy Markdown
Member

Stacked on #309 (FDv2 source-layer translation); that lands first.

What this adds

The streaming half of the FDv2 source factories, plus the authentication plumbing both source kinds share. Nothing constructs these factories in production yet (the orchestrator consumes them in a later PR), so behavior is unchanged.

Streaming factories

createSynchronizerFactoryFromEntry now builds FDv2StreamingSynchronizers instead of throwing UnsupportedError. The SSE client is constructed with a uriProvider that is re-invoked on every connection attempt, so the basis query parameter always reflects the current selector — a reconnect after payloads have been applied resumes with a delta request rather than refetching the full payload. The URI builder composes against the configured base URI the same way the polling requestor does (path joining without clobbering existing query parameters).

Query-parameter authentication

SourceFactoryContext gains additionalQueryParameters, applied to every data acquisition request by both FDv2 transports — streaming through the uriProvider, and polling through FDv2Requestor, which merges them into each poll URL. The transports are agnostic about what the parameters carry; authentication enters at the single population site, where SourceFactoryContext.fromClientConfig supplies the platform CredentialConfig.authQueryParameters: empty on io (every io transport authenticates with the authorization header in the base headers) and auth=<client-side-id> on web.

The web platform authenticates with the query parameter at all times rather than the authorization header: a browser only delivers that header when the target service's CORS pre-flight allows it, the browser's native EventSource cannot send custom headers at all, and the FDv2 endpoint paths do not embed the credential the way the FDv1 client-side paths do. (Requirement 3.1.3 of the client-side FDv2 spec, added in launchdarkly/sdk-specs#233, permits this.) Verified against the live service: the FDv2 polling endpoint returns 200 with ?auth=<credential> and 400 without.

Testing

Factory tests cover the streaming construction path and pin the URI contract: the streaming URI carries the auth query parameters and picks up the current selector's basis on each provider invocation, and the polling request URL carries the auth parameters through the factory wiring. Requestor tests assert the additional query parameters appear on every poll URL alongside basis, and that the requestor adds no authorization header (authentication comes from base headers or query parameters, never per-request). Full package suite passes.

SDK-2186


Note

Medium Risk
Touches authentication query parameters and streaming connection/error handling; production behavior is unchanged until the orchestrator wires these factories, but mistakes could break web auth or fallback when enabled.

Overview
Adds FDv2 streaming synchronizer factory wiring so StreamingSynchronizer entries build FDv2StreamingSynchronizer with an SSE client whose uriProvider is rebuilt on each connect, keeping basis aligned with the current selector for delta resumes after reconnect.

Introduces shared buildFDv2Uri for polling and streaming so paths, withReasons, basis, relay-style base query strings (including duplicate keys), and extra params merge the same way. SourceFactoryContext now carries credential and additionalQueryParameters (from CredentialConfig.authQueryParameters, e.g. web auth=), applied on every poll and stream URL via FDv2Requestor and the streaming URI builder.

FDv2StreamingBase gains optional defaultEnvironmentId when headers are unavailable, and treats UnrecoverableStatusError as a terminal failure (with optional x-ld-fd-fd-fallback). Factory and requestor tests cover auth query params, basis on reconnect, and repeated relay query keys.

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

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.

After some discussion and consideration I decided that the auth for the browser may as well always use the query parameter. This reduces the risk of a cors problem.

@kinyoklion kinyoklion force-pushed the rlamb/sdk-2186/fdv2-streaming-source branch 2 times, most recently from f171045 to 1ae2779 Compare June 12, 2026 22:47
@kinyoklion kinyoklion force-pushed the rlamb/sdk-2186/fdv2-streaming-source branch 3 times, most recently from 563d243 to 53f8ce2 Compare June 12, 2026 22:56
@kinyoklion kinyoklion marked this pull request as ready for review June 12, 2026 22:59
@kinyoklion kinyoklion requested a review from a team as a code owner June 12, 2026 22:59
@kinyoklion kinyoklion force-pushed the rlamb/sdk-2186/fdv2-streaming-source branch from 53f8ce2 to 5d95350 Compare June 15, 2026 18:33
@kinyoklion kinyoklion changed the base branch from main to rlamb/sdk-2186/fdv2-source-translation June 15, 2026 18:33
@kinyoklion kinyoklion force-pushed the rlamb/sdk-2186/fdv2-streaming-source branch from b4f1251 to 651a7ad Compare June 15, 2026 19:52

@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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 651a7ad. Configure here.

…ication

Adds the streaming half of the FDv2 source factories and the shared
authentication plumbing. The streaming synchronizer is built with a
per-attempt uriProvider so the basis query parameter tracks the current
selector across reconnects. additionalQueryParameters (the auth query
parameter on web, empty on mobile) is applied to every request URL by
both transports.

Both transports build request URLs through one shared buildFDv2Uri
helper, so query-parameter merging is identical -- including preserving
repeated keys on a custom (relay-style) base URL, which the streaming
builder previously collapsed.
@kinyoklion kinyoklion force-pushed the rlamb/sdk-2186/fdv2-streaming-source branch from 651a7ad to 187332d Compare June 15, 2026 21:13
@kinyoklion kinyoklion merged commit a42f5ce into rlamb/sdk-2186/fdv2-source-translation Jun 15, 2026
5 checks passed
@kinyoklion kinyoklion deleted the rlamb/sdk-2186/fdv2-streaming-source branch June 15, 2026 21:44
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.

3 participants