Skip to content

fix(browser-sdk): respect native EventSource reconnection - #794

Open
roncohen wants to merge 2 commits into
mainfrom
fix/browser-sse-native-reconnect
Open

roncohen wants to merge 2 commits into
mainfrom
fix/browser-sse-native-reconnect

Conversation

@roncohen

@roncohen roncohen commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Let the browser's built-in EventSource reconnect recoverable failures without closing/recreating it in the SDK.
  • Respect native terminal failures, including HTTP 403, instead of restarting rejected connections every 30 seconds.
  • Track the actual open event separately from an in-flight connection, avoid duplicate connections, and ignore events from closed/replaced sources.
  • Leave the existing React Native/custom transport retry policy unchanged.
  • Add a browser SDK patch changeset, transport unit regressions, actual React Native transport recovery tests, and real-browser tests using a local HTTP/SSE server.

Why

connect() resolves after constructing EventSource, before the HTTP handshake completes. The previous browser retry loop reset its budget at that point, so subsequent asynchronous authentication errors never exhausted the budget.

The error handler also closed every EventSource, cancelling the browser's own recoverable reconnects. The SDK interval then constructed a new source even after the browser had classified an HTTP rejection as terminal.

This change uses native retry semantics rather than adding another browser backoff/jitter loop. Native EventSource treats non-200 handshake responses as terminal, not only 403; this PR deliberately respects that classification. Explicit client stop/reinitialization remains supported.

React Native compatibility

The RN wrapper injects react-native-sse with pollingInterval: 0, so it depends on SDK-managed retries. An earlier revision of this PR made asynchronous custom-transport failures exhaust a finite retry budget. Review reproduced a regression: an ordinary mobile network outage lasting more than about two minutes permanently disabled live updates after connectivity returned.

That policy change has been removed. Custom transports retain their existing behavior: synchronous setup failures are bounded, while asynchronous failures can continue retrying and recover after a prolonged outage. Custom-transport authentication retry policy is deliberately outside this browser-focused fix.

New tests use the actual react-native-sse implementation with mocked XMLHttpRequest, rather than only a generic EventSource mock. They cover starting offline and losing an established connection, three minutes offline followed by recovery, message delivery after reconnection, and cancellation on close. Both tests fail against the earlier PR revision and pass with this follow-up. react-native-sse is added only as a browser SDK dev dependency, using the same version range as the RN wrapper.

Validation

  • yarn test: 954 tests pass across all 10 test workspaces, including 218 browser SDK tests.
  • Focused SSE suites: 25 tests pass, including the two actual RN transport regressions.
  • Complete browser E2E suite in Chromium and Firefox: 38/38 pass on the updated code. Initial 403s remain terminal, recoverable disconnects use native reconnection, and explicit stop/reinitialization works.
  • Browser SDK and dependent React, Vue, React Native, and OpenFeature browser package builds pass.
  • yarn install --immutable, yarn lint:fix, yarn fmt, and git diff --check pass (one existing lint warning in the management example's next-env.d.ts).
  • Browser source/test typecheck passes with --target ES2020.
  • Earlier negative control confirmed that the new initial-403 E2E test fails against the base implementation because it recreates rejected connections after advancing SDK timers.

Local environment limitations

  • Full yarn build stops in the unrelated management SDK generator because Java is not installed. Its generated-file deletions were restored; no generated files are included in this PR.
  • WebKit cannot launch locally because required system libraries are missing. The tests remain included in the existing three-browser CI configuration.
  • The default all-test typecheck encounters the existing BigInt literal in test/context.test.ts with the inherited pre-ES2020 target; the ES2020 override above passes.
  • RN validation exercises the real transport against mocked XMLHttpRequest, not an iOS/Android device or simulator.

No deployment, production configuration, or credential changes.

Copilot AI balanced review requested due to automatic review settings November 5, 2026 11:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The SSE lifecycle changes have no active review issues.

No open issues 🎉

What changed in this PR

This PR updates the browser SDK’s SSE lifecycle to respect native EventSource reconnection and terminal failures while preserving bounded SDK retries for custom transports.

Changes:

  • Delegate native reconnection to the browser and reset custom retry budgets only after an open event.
  • Track pending and open connections separately, prevent duplicates, and ignore events from closed or replaced sources.
  • Add unit and real-browser regression tests, plus a patch changeset.
File Description
packages/​browser-sdk/​test/​sse.test.ts Adds coverage for connection state, native reconnection, stale events, and custom retry limits.
packages/​browser-sdk/​test/​e2e/​sse.browser.spec.ts Adds local-server browser tests for HTTP 403, reconnection, stopping, and reinitialization.
packages/​browser-sdk/​src/​sse.ts Separates native and custom retry handling and improves connection lifecycle tracking.
.changeset/​tidy-rivers-reconnect.md Documents the browser SDK patch release.

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 5, 2026 11:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues remain for the browser SDK reconnection changes.

No open issues 🎉

Review effort: Balanced

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