Skip to content

Commit f92a8f9

Browse files
authored
fix: adding wrapper name for react client (#1199)
<!-- CURSOR_SUMMARY --> > [!NOTE] > **Low Risk** > Low risk: this only adjusts how `createClient` builds options for the underlying JS client and adds focused unit tests; runtime behavior changes are limited to default `wrapperName`/`wrapperVersion` values sent to the base SDK. > > **Overview** > `createClient` in the React SDK now injects default `wrapperName` (`react-client-sdk`) and `wrapperVersion` into the options passed to `@launchdarkly/js-client-sdk`, while still merging user-provided options and allowing explicit overrides. > > Adds unit tests covering wrapper option behavior, and updates `release-please-config.json` so `LDReactClient.tsx` is included in version bump automation. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 8efb1e5. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- devin-review-badge-begin --> --- <a href="https://app.devin.ai/review/launchdarkly/js-core/pull/1199" target="_blank"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1"> <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open with Devin"> </picture> </a> <!-- devin-review-badge-end -->
1 parent 10d33d2 commit f92a8f9

3 files changed

Lines changed: 70 additions & 8 deletions

File tree

packages/sdk/react/__tests__/client/LDReactClient.test.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,3 +321,52 @@ it('noop client onInitializationStatusChange returns a no-op unsubscribe', () =>
321321
// @ts-ignore
322322
global.window = originalWindow;
323323
});
324+
325+
it('passes wrapperName to the base client', () => {
326+
const { mock } = makeMockBaseClient();
327+
(createBaseClient as jest.Mock).mockReturnValue(mock);
328+
329+
createClient('test-id', { kind: 'user', key: 'u1' });
330+
331+
expect(createBaseClient).toHaveBeenCalledWith(
332+
'test-id',
333+
{ kind: 'user', key: 'u1' },
334+
expect.objectContaining({ wrapperName: 'react-client-sdk' }),
335+
);
336+
});
337+
338+
it('preserves user-provided options alongside wrapper defaults', () => {
339+
const { mock } = makeMockBaseClient();
340+
(createBaseClient as jest.Mock).mockReturnValue(mock);
341+
342+
createClient('test-id', { kind: 'user', key: 'u1' }, { streaming: false });
343+
344+
expect(createBaseClient).toHaveBeenCalledWith(
345+
'test-id',
346+
{ kind: 'user', key: 'u1' },
347+
expect.objectContaining({
348+
wrapperName: 'react-client-sdk',
349+
streaming: false,
350+
}),
351+
);
352+
});
353+
354+
it('user-provided wrapperName/wrapperVersion overrides defaults', () => {
355+
const { mock } = makeMockBaseClient();
356+
(createBaseClient as jest.Mock).mockReturnValue(mock);
357+
358+
createClient(
359+
'test-id',
360+
{ kind: 'user', key: 'u1' },
361+
{
362+
wrapperName: 'custom',
363+
wrapperVersion: '9.9.9',
364+
},
365+
);
366+
367+
expect(createBaseClient).toHaveBeenCalledWith(
368+
'test-id',
369+
{ kind: 'user', key: 'u1' },
370+
expect.objectContaining({ wrapperName: 'custom', wrapperVersion: '9.9.9' }),
371+
);
372+
});

packages/sdk/react/src/client/LDReactClient.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import {
55
type LDEvaluationDetailTyped,
66
LDEvaluationReason,
77
type LDFlagValue,
8+
LDIdentifyOptions,
9+
LDIdentifyResult,
10+
LDOptions,
811
LDStartOptions,
912
LDWaitForInitializationResult,
1013
} from '@launchdarkly/js-client-sdk';
@@ -107,14 +110,21 @@ function createNoopReactClient(): LDReactClient {
107110
export function createClient(
108111
clientSideID: string,
109112
context: LDContext,
110-
options?: LDReactClientOptions,
113+
options: LDReactClientOptions = {},
111114
): LDReactClient {
112115
if (isServerSide()) {
113116
return createNoopReactClient();
114117
}
115-
const shouldUseCamelCaseFlagKeys = options?.useCamelCaseFlagKeys ?? true;
116118

117-
const baseClient = createBaseClient(clientSideID, context, options);
119+
const { useCamelCaseFlagKeys: shouldUseCamelCaseFlagKeys = true, ...ldOptions } = options;
120+
121+
const baseClientOptions: LDOptions = {
122+
...ldOptions,
123+
wrapperName: ldOptions?.wrapperName ?? 'react-client-sdk',
124+
wrapperVersion: ldOptions?.wrapperVersion ?? '0.0.0', // x-release-please-version
125+
};
126+
127+
const baseClient = createBaseClient(clientSideID, context, baseClientOptions);
118128
let initializationState: InitializedState = 'unknown';
119129
const subscribers = new Set<(context: LDContextStrict) => void>();
120130
const initStatusSubscribers = new Set<(result: LDWaitForInitializationResult) => void>();
@@ -129,15 +139,15 @@ export function createClient(
129139
return baseClient.start(startOptions);
130140
}
131141
initializationState = 'initializing';
132-
return baseClient.start(startOptions).then((result) => {
142+
return baseClient.start(startOptions).then((result: LDWaitForInitializationResult) => {
133143
initializationState = result.status;
134144
lastInitResult = result;
135145
initStatusSubscribers.forEach((cb) => cb(result));
136146
return result;
137147
});
138148
},
139-
identify: (...args) =>
140-
baseClient.identify(...args).then((result) => {
149+
identify: (ldContext: LDContext, identifyOptions?: LDIdentifyOptions) =>
150+
baseClient.identify(ldContext, identifyOptions).then((result: LDIdentifyResult) => {
141151
if (result.status === 'completed') {
142152
const newContext = baseClient.getContext();
143153
if (newContext) {
@@ -149,7 +159,7 @@ export function createClient(
149159
getInitializationState: () => initializationState,
150160
getInitializationError: () =>
151161
lastInitResult?.status === 'failed' ? lastInitResult.error : undefined,
152-
onContextChange: (callback: (context: LDContextStrict) => void) => {
162+
onContextChange: (callback: (ldContext: LDContextStrict) => void) => {
153163
subscribers.add(callback);
154164
return () => {
155165
subscribers.delete(callback);

release-please-config.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,10 @@
104104
"bump-minor-pre-major": true
105105
},
106106
"packages/sdk/react": {
107-
"bump-minor-pre-major": true
107+
"bump-minor-pre-major": true,
108+
"extra-files": [
109+
"src/client/LDReactClient.tsx"
110+
]
108111
}
109112
},
110113
"plugins": [

0 commit comments

Comments
 (0)