diff --git a/packages/sdk/browser/README.md b/packages/sdk/browser/README.md index b26aac5231..4226bfb040 100644 --- a/packages/sdk/browser/README.md +++ b/packages/sdk/browser/README.md @@ -6,25 +6,6 @@ [![NPM][browser-sdk-dm-badge]][browser-sdk-npm-link] [![NPM][browser-sdk-dt-badge]][browser-sdk-npm-link] -# ⛔️⛔️⛔️⛔️ - -> [!CAUTION] -> This library is a alpha version and should not be considered ready for production use while this message is visible. - -# ☝️☝️☝️☝️☝️☝️ - - - ## Getting started Refer to the [SDK documentation](https://docs.launchdarkly.com/sdk/client-side/javascript#getting-started) for instructions on getting started with using the SDK. diff --git a/packages/sdk/browser/upgrade/README.md b/packages/sdk/browser/upgrade/README.md deleted file mode 100644 index a63598ac53..0000000000 --- a/packages/sdk/browser/upgrade/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Upgrade docs - -This directory contains the guides on how to -upgrade between major versions of the js client sdk. - -## Contents - -- [Updating to version 4.0.0](v4.md) \ No newline at end of file diff --git a/packages/sdk/browser/upgrade/v4.md b/packages/sdk/browser/upgrade/v4.md deleted file mode 100644 index 1d8415dc0b..0000000000 --- a/packages/sdk/browser/upgrade/v4.md +++ /dev/null @@ -1,240 +0,0 @@ -# Upgrading to `@launchdarkly/js-client-sdk@4` - -## Overview -Starting from js client sdk version 4, we've moved our source to -this monorepo and the node module will be named `@launchdarkly/js-client-sdk` -moving forward. - -As such, the first steps to updating is installing the "new" package and swapping -all references from `launchdarkly-js-client-sdk` to `@launchdarkly/js-client-sdk`. - -Below, you can find the potentially breaking changes that you will need to address to -successfully upgrade. - -## Key changes - -### Client initialization - -**Key differences:** -- Initialization is now split into 2 parts `createClient` and `start` -- We split the original `LDOptions` that was passed into the `initialize()` function into - 2 types `LDStartOptions` and `LDOptions`. [more here](#ldoptions) -- Removed the use of `initialize` method - -**Before (v3.x):** -```javascript -import LDClient from 'launchdarkly-js-client-sdk'; - -const client = LDClient.initialize('client-side-id', context, options); -``` - -**After (v4.x):** -```javascript -import { createClient } from '@launchdarkly/js-client-sdk'; - -// Create client -const client = createClient('client-side-id', context, options); - -// Then start the client -client.start(); -``` - -**Why this change?** -This two-step process ensures that you can register all event listeners and -perform any necessary setup before the client begins connecting to LaunchDarkly. -This eliminates race conditions where events might be missed if listeners were -registered after the client had already started initializing. - -### LDOptions - -We moved a few things around in `LDOptions` to support the changes that are discussed in -other parts of this doc. Please visit the following docs to see how to interact with our SDK: -- [LDOptions](https://launchdarkly.github.io/js-core/packages/sdk/browser/docs/interfaces/LDOptions.html) that is passed into `createClient()` -- [LDStartOptions](https://launchdarkly.github.io/js-core/packages/sdk/browser/docs/interfaces/LDStartOptions.html) that is passed into `start()` -- [LDIdentifyOptions](https://launchdarkly.github.io/js-core/packages/sdk/browser/docs/interfaces/LDIdentifyOptions.html) that is passed into `identify()` - -**Key differences:** -- `bootstrap` option is moved from `LDOptions` to `LDStartOptions` and `Identify`. The reason for this is that bootstrapping data is - now part of the initialization of a client instance. - > NOTE: that `identify` is a key part of the client initialization process required to associate the instance with an initial context. -- The SDK now defaults to use local storage based caching. - > Previously, in order enable local storage caching, you will need to set this as a special value for the `bootstrap` property. - -### Client initialization flow - -The new SDK uses `waitForInitialization()` which returns a result object instead of rejecting promises. -The old `waitUntilReady()` method has been removed. - -**Key differences:** -- `waitForInitialization()` now always resolves (never rejects) and returns a result object with a `status` field -- The `timeout` is now specified as an option object: `{ timeout: 5 }` instead of a direct parameter -- `waitUntilReady()` has been removed - use `waitForInitialization()` instead -- The result object allows you to handle all cases (success, failure, timeout) without try/catch - -**Before (v3.x):** -```javascript -// Option 1: Using waitUntilReady (never rejects) -await client.waitUntilReady(); - -// Option 2: Using waitForInitialization (rejects on failure) -try { - await client.waitForInitialization(5); -} catch (err) { - // Failure - but this could be an unhandled rejection if not caught -} - -// Option 3: Using event listeners -client.on('ready', () => { - // Client is ready (success or failure) -}); -client.on('initialized', () => { - // Client initialized successfully -}); -client.on('failed', (err) => { - // Client failed to initialize -}); -``` - -**After (v4.x):** -```javascript -// Recommended: Using waitForInitialization (always resolves with status) -const result = await client.waitForInitialization({ timeout: 5 }); - -if (result.status === 'complete') { - // Client initialized successfully -} else if (result.status === 'failed') { - // Client failed to initialize - console.error('Initialization failed:', result.error); -} else if (result.status === 'timeout') { - // Initialization timed out - console.error('Initialization timed out'); -} - -// Note: Events still work if you prefer that approach -client.on('ready', () => { - // Client is ready (success or failure) -}); -client.on('initialized', () => { - // Client initialized successfully -}); -client.on('failed', (err) => { - // Client failed to initialize -}); -``` - -### Identify - -The `identify()` method now always returns a result object and never throws errors. -This provides more predictable error handling. - -**Key differences:** -- `identify()` now takes an options object as the second parameter: `LDIdentifyOptions` instead of a direct hash string -- The method always returns a promise that resolves to a result object (never rejects) -- You must check the `status` field to determine success or failure -- The `hash` parameter is now part of the options object -- `IdentifyOptions` now have a `sheddable` property that is `true` by default. Which means the default behavior for - multiple identify calls is different - [more info here](https://launchdarkly.github.io/js-core/packages/sdk/browser/docs/interfaces/LDIdentifyOptions.html#sheddable) -- Callback support has been removed - use async/await or `.then()` instead -> See [options section](#ldoptions) for more information about changes to the options. - -**Before (v3.x):** -```javascript -// Option 1: Using callback -client.identify(newContext, hash, (err, flags) => { - if (err) { - // Handle error - } else { - // Use flags - } -}); - -// Option 2: Using promise (could throw) -try { - const flags = await client.identify(newContext, hash); - // Use flags -} catch (err) { - // Handle error - but this might be an unhandled rejection -} -``` - -**After (v4.x):** -```javascript -// Always returns a result object, never throws -const result = await client.identify(newContext, { hash }); - -if (result.status === 'completed') { - // Identification completed successfully -} else if (result.status === 'error') { - // Identification encountered an error -} else if (result.status === 'timeout') { - // Identification timed out -} else if (result.status === 'shed') { - // Identification was shed (discarded due to multiple rapid calls) - // This can happen when sheddable option is enabled -} -``` - -### Flag change event payload - -The `change` event now receives the context and an array of changed flag keys as parameters. -> NOTE: we will no longer return the flag value object along with this event - -**Key differences:** -- The `change` event listener now receives `(context, changedFlagKeys)` where `changedFlagKeys` is an array of strings -- The event does not include flag values - you must call `variation()` to get the current value -- Similarly `change:` event listener will now only recieve `(context)` - -**Before (v3.x):** -```javascript -// The exact signature may have varied, but typically: -client.on('change', (changedFlags) => { - // changedFlags is a key value pair where the flag key is mapped - // to a diff object. -}); -``` - -**After (v4.x):** -```javascript -// General change event - fires when any flags change -client.on('change', (context, changedFlagKeys) => { - // context: The LDContext for which flags changed - // changedFlagKeys: Array of flag keys that changed - - // Still need to call variation() to get current values - changedFlagKeys.forEach(flagKey => { - const flagValue = client.variation(flagKey, defaultValue); - }); -}); - -// Specific flag change event - fires when a specific flag changes -client.on('change:my-flag', (context) => { - // Only fires when 'my-flag' changes - const flagValue = client.variation('my-flag', false); -}); -``` - -### Error event handling changes - -The new SDK has changed how errors are logged when error event listeners are present. - -**Key difference:** - -**Before (v3.x):** -In the old SDK, the `maybeReportError` function would check if there was an error listener: -- If an error listener was registered: the error event was emitted but **not logged** to the console -- If no error listener was registered: the error was logged to the console - -> This meant that if you wanted to handle errors yourself, you wouldn't get duplicate error logs. - -**After (v4.x):** -In the new SDK, the client always registers a default error listener that logs errors via the logger. This means: -- Errors are **always logged** via the logger, even if you have your own error listeners -- Your error listeners will still receive the error events -- You may see duplicate error logs if you're also logging errors in your error handler - -**Why this change?** -The new error handling process allows for more robust control over what errors are ignored. The specific case -that we want to avoid is not logging/informing end users when an unhandled error happens. - -Our recommendation is to implement `LDLogger` for your client to suppress errors that are handled diff --git a/release-please-config.json b/release-please-config.json index 4d92576400..2f9d7a5fa3 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -86,7 +86,7 @@ "packages/store/node-server-sdk-redis": {}, "packages/telemetry/node-server-sdk-otel": {}, "packages/sdk/browser": { - "bump-minor-pre-major": true, + "release-as": "4.0.0", "extra-files": [ "src/platform/BrowserInfo.ts" ]