Skip to content

chore: support running multiple clients with same client id#1253

Draft
joker23 wants to merge 1 commit intomainfrom
skz/sdk-1907/electron-multi-env
Draft

chore: support running multiple clients with same client id#1253
joker23 wants to merge 1 commit intomainfrom
skz/sdk-1907/electron-multi-env

Conversation

@joker23
Copy link
Copy Markdown
Contributor

@joker23 joker23 commented Apr 7, 2026

This PR will implement support for running multiple LDClients with the same mobile key. We do this by adding an optional namespace option that will prefix the persistent storage path so there won't be any collisions.

I also reduce some redundant code in the __test__ repo as it was getting unwieldy


Note

Medium Risk
Changes how storage paths and IPC channel names are derived (hashed namespace, optional user namespace), which can affect multi-client behavior and any code assuming the old channel naming/bridge signature. Backward compatibility is intended when namespace is omitted, but misconfiguration could lead to unexpected client isolation or collisions.

Overview
Adds an optional namespace option to the Electron SDK to allow multiple client instances using the same credential to coexist without colliding on persisted cache or IPC handler/channel names.

Introduces deriveNamespace() (SHA-256 of credential or namespace:credential) and threads the derived value through main-process storage (ElectronPlatform/ElectronStorage), main-process IPC registration (ElectronClient), and renderer IPC bridge creation (ldClientBridge, ElectronRendererClient, createRendererClient).

Updates/extends tests (including new ElectronIPC unit tests and contract-test entity wiring) and refactors test utilities (shared createMockLogger + table-driven variation tests); docs add migration guidance for using namespace with multiple clients.

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

@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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

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

@joker23 joker23 force-pushed the skz/sdk-1907/electron-multi-env branch 3 times, most recently from 4c9b14f to 5809629 Compare April 8, 2026 17:57
@joker23
Copy link
Copy Markdown
Contributor Author

joker23 commented Apr 8, 2026

@cursor review

Copy link
Copy Markdown

@cursor cursor bot left a comment

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 and found 2 potential issues.

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 5809629. Configure here.

ipcRenderer.sendSync(getIPCChannelName(namespace, 'removeEventHandler'), callbackId),
});
const ldClientBridge = (credential: string, namespace?: string): LDClientBridge => {
const ipcNs = deriveNamespace(credential, namespace);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bridge preload now requires Node.js crypto module

Medium Severity

The bridge module (used as an Electron preload script) now transitively imports createHash from Node.js crypto via deriveNamespace in ElectronIPC.ts. Previously, the bridge only depended on electron APIs (ipcRenderer, contextBridge) which are available in sandboxed preload scripts. The crypto module is not in the limited set of Node.js modules available in Electron's sandboxed preload context (only events, timers, url are). Since sandbox is Electron's default, this could break the bridge for users who don't further bundle their preload scripts with a polyfill.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5809629. Configure here.

*/
export function deriveNamespace(credential: string, userNamespace?: string): string {
const input = userNamespace ? `${userNamespace}:${credential}` : credential;
return createHash('sha256').update(input).digest('base64url');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Empty string namespace silently treated as no namespace

Low Severity

deriveNamespace uses a JavaScript truthiness check (userNamespace ? ...) which treats an empty string '' identically to undefined. Since TypeValidators.String accepts empty strings, a user can set namespace: '' and it silently behaves like no namespace was set. Two clients with the same credential — one with namespace: '' and one with no namespace — would collide on storage and IPC channels.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5809629. Configure here.

@joker23 joker23 force-pushed the skz/sdk-1907/electron-multi-env branch from 5809629 to cc53988 Compare April 8, 2026 19:28
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.

1 participant