Skip to content

Commit eff6a55

Browse files
authored
refactor!: align browser v4 intialization flow to specs (#1040)
**Requirements** - [x] I have added test coverage for new or changed functionality - [x] I have followed the repository's [pull request submission guidelines](../blob/main/CONTRIBUTING.md#submitting-pull-requests) - [x] I have validated my changes against all supported platform versions **Related issues** sdk-1667 **Describe the solution you've provided** - Introduced `start` method in `BrowserClient` to handle client initialization. - Replaced direct calls to identify with `setInitialContext` and `start` for better context management. - Updated example app to reflect changes in client initialization and context handling. - Added tests to ensure proper functionality of new initialization flow. **Additional context** - The main motiviation behind this change is to present a more organized front on when a client is starting. - I'll be making a task to push this behavior down to the shared client code as an optional start and start adding a deprecated message on the old flow. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds an explicit client start() flow and new createClient API (with required initial context), updates initialization/identify behavior, and refreshes tests, examples, and compat layer accordingly. > > - **API/Initialization**: > - Add `LDClient.start(options?)` returning `LDWaitForInitializationResult`; cache promise; support `bootstrap` via `start`/`identifyOptions`. > - Replace `initialize(...)` with `createClient(clientSideId, context, options)`; `makeClient` now requires an initial `LDContext`. > - Disallow `identify` before `start` (returns `{ status: 'error' }` and logs); initial `identify` is non-sheddable. > - Normalize init statuses: `waitForInitialization` returns `{ status: 'complete' | 'failed' | 'timeout' }` (note: some tests updated from `error`→`failed`). > - Make `LDWaitForInitializationOptions.timeout` optional; add `LDStartOptions`. > - **BrowserClient**: > - Track `_initialContext`, `_startPromise`, `_initializedPromise`; preset flags from `bootstrap` before identify. > - Update plugin registration/hook calls to run through new flow; continue goal tracking logic, URL transformation for events. > - **Compat (`/compat`)**: > - `initialize(envKey, context, options)` now builds via `makeClient(envKey, context, ...)`; immediately `start()` then perform `identify` to mirror old behavior; re-export unchanged surface minus `start`/`setInitialContext`. > - **Examples/Contract Tests**: > - Update example app and contract entity to use `createClient(..., context)` and `client.start()` + `waitForInitialization()`. > - **Tests**: > - Revise unit tests to use `start()` and required initial context; add cases for start idempotency, shedding order, bootstrap pre-eval, URL filtering, waitForInitialization timing/failure. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 846ae61. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 17f5e7d commit eff6a55

File tree

11 files changed

+294
-75
lines changed

11 files changed

+294
-75
lines changed

packages/sdk/browser/__tests__/BrowserClient.plugins.test.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ it('registers plugins and executes hooks during initialization', async () => {
4141

4242
const platform = makeBasicPlatform();
4343

44+
const context: LDContext = { key: 'user-key', kind: 'user' };
4445
const client = makeClient(
4546
'client-side-id',
47+
context,
4648
AutoEnvAttributes.Disabled,
4749
{
4850
streaming: false,
@@ -55,10 +57,7 @@ it('registers plugins and executes hooks during initialization', async () => {
5557

5658
// Verify the plugin was registered
5759
expect(mockPlugin.register).toHaveBeenCalled();
58-
59-
// Now test that hooks work by calling identify and variation
60-
const context: LDContext = { key: 'user-key', kind: 'user' };
61-
await client.identify(context);
60+
await client.start();
6261

6362
expect(mockHook.beforeIdentify).toHaveBeenCalledWith({ context, timeout: undefined }, {});
6463

@@ -134,6 +133,7 @@ it('registers multiple plugins and executes all hooks', async () => {
134133

135134
const client = makeClient(
136135
'client-side-id',
136+
{ key: 'user-key', kind: 'user' },
137137
AutoEnvAttributes.Disabled,
138138
{
139139
streaming: false,
@@ -149,7 +149,7 @@ it('registers multiple plugins and executes all hooks', async () => {
149149
expect(mockPlugin2.register).toHaveBeenCalled();
150150

151151
// Test that both hooks work
152-
await client.identify({ key: 'user-key', kind: 'user' });
152+
await client.start();
153153
client.variation('flag-key', false);
154154
client.track('event-key', { data: true }, 42);
155155

@@ -200,6 +200,7 @@ it('passes correct environmentMetadata to plugin getHooks and register functions
200200

201201
makeClient(
202202
'client-side-id',
203+
{ kind: 'user', key: '', anonymous: true },
203204
AutoEnvAttributes.Disabled,
204205
{
205206
streaming: false,
@@ -281,6 +282,7 @@ it('passes correct environmentMetadata without optional fields', async () => {
281282

282283
makeClient(
283284
'client-side-id',
285+
{ kind: 'user', key: '', anonymous: true },
284286
AutoEnvAttributes.Disabled,
285287
{
286288
streaming: false,

0 commit comments

Comments
 (0)