All notable changes to the LaunchDarkly Client-Side SDK for Node.js will be documented in this file.
3.3.0 (2024-10-18)
- Updated
launchdarkly-evensource
to version2.0.3
which includes improvements to error handling and shutdown of SSE streams.
- Added an optional timeout to the
waitForInitialization
method. When a timeout is specified the returned promise will be rejected after the timeout elapses if the client has not finished initializing within that time. When no timeout is specified the returned promise will not be resolved or rejected until the initialization either completes or fails.
- The track method now validates that the provided metricValue is a number. If a metric value is provided, and it is not a number, then a warning will be logged.
- Fixed the documentation for
evaluationReasons
for theidentify
method. - Upgraded to launchdarkly-eventsource version 2.0.2. This version contains performance improvements and logging improvements compared the the version that was in use.
- Redact anonymous attributes within feature events
- Always inline contexts for feature events
- Update
LDContext
to allow for key to be optional. This is used when making an anonymous context with a generated key.
- Upgrade to
js-sdk-common
version5.0.2
. This removes usage of optional chaining (?.
) to allow for use with older transpilers.
The latest version of this SDK supports LaunchDarkly's new custom contexts feature. Contexts are an evolution of a previously-existing concept, "users." Contexts let you create targeting rules for feature flags based on a variety of different information, including attributes pertaining to users, organizations, devices, and more. You can even combine contexts to create "multi-contexts."
For detailed information about this version, please refer to the list below. For information on how to upgrade from the previous version, please read the migration guide.
- The types
LDContext
,LDSingleKindContext
, andLDMultiKindContext
define the new "context" model. - All SDK methods that took an
LDUser
parameter now take anLDContext
.LDUser
is now a subset ofLDContext
, so existing code based on users will still work.
- There is no longer such a thing as a
secondary
meta-attribute that affects percentage rollouts. If you set an attribute with that name inLDContext
, it will simply be a custom attribute like any other. - Evaluations now treat the
anonymous
attribute as a simple boolean, with no distinction between a false state and an undefined state. LDClient.getUser
has been replaced withLDClient.getContext
.privateAttributeNames
has been replaced withprivateAttributes
inLDOptions
. Private attributes now allow using attribute references.- Update the version of typedoc used for documentation generation, and update the documentation generation process.
- Analytics event data now uses a new JSON schema due to differences between the context model and the old user model.
- Removed all types, fields, and methods that were deprecated as of the most recent 3.x release.
- Removed the
secondary
meta-attribute inLDUser
. - The
alias
method no longer exists because alias events are not needed in the new context model. - The
autoAliasingOptOut
andinlineUsersInEvents
options no longer exist because they are not relevant in the new context model.
- The
LDUser
object has been deprecated. Support forLDUser
is maintained to simplify the upgrade process, but it is recommended to useLDContext
in the shape of eitherLDSingleKindContext
orLDMultiKindContext
.
- Upgraded to
js-sdk-common
version4.3.3
which fixed this issue: Warning: Accessing non-existent property 'messages' of module exports inside circular dependency
- Upgraded to
js-sdk-common
version4.3.2
which includes implementations ofjitter
andbackoff
for streaming connections. When a connection fails the retry will start at thestreamReconnectDelay
and will double on each unsuccessful consecutive connection attempt (backoff
) to a max of 30 seconds. The delay will be adjusted from 50%-100% of the calculated delay to prevent many clients from attempting to reconnect at the same time (jitter
).
- Upgrade to
js-sdk-common
4.3.1
which added support forInspectors
that can be used for collecting information for monitoring, analytics, and debugging.
-
Updated
js-sdk-common
version which removed event de-duplication functionality which was made redundant by support of summary events. This will improve the default event behavior when using experimentation. -
Updated development dependencies to recent versions.
-
Updated CI builds to current node LTS versions and dropped build support for node 12.
- CI builds now include a cross-platform test suite implemented in https://github.com/launchdarkly/sdk-test-harness. This covers many test cases that are also implemented in unit tests, but may be extended in the future to ensure consistent behavior across SDKs in other areas.
- The
baseUrl
,streamUrl
, andeventsUrl
properties now work properly regardless of whether the URL string has a trailing slash. Previously, a trailing slash would cause request URL paths to have double slashes.
- The
original
dependency (and therefore its transitive dependencyurl-parse
) had accidentally been included twice, once as a dependency ofjs-eventsource
and then again directly in the SDK'spackage.json
. This has been removed so there is no longer any reference to the vulnerableurl-parse
that was meant to be removed in 2.0.2. (Thanks, AlexHladin!)
- Removed a transitive dependency on the package
url-parse
, which was flagged in CVE-2022-0686.
- If the SDK receives invalid JSON data from a streaming connection (possibly as a result of the connection being cut off), it now uses its regular error-handling logic: the error is emitted as an
error
event or, if there are noerror
event listeners, it is logged. Previously, the error would be thrown as an unhandled exception.
This major version release is for updating Node.js compatibility, simplifying the SDK's dependencies, and removing deprecated names.
Except for the dependency changes described below which may require minor changes in your build, and a minor new logging feature, usage of the SDK has not changed in this release. For more details about changes that may be necessary, see the 1.x to 2.0 migration guide.
Dropping support for obsolete Node.js versions makes it easier to maintain the SDK and keep its dependencies up to date. See LaunchDarkly's End of Life Policy regarding platform version support.
Simplifying dependencies reduces the size of the SDK bundle, as well as reducing potential compatibility problems and vulnerabilities.
- Added
basicLogger
, allowing customization of the SDK's default logging behavior without having to use Winston or provide a fullLDLogger
implementation.
- The minimum Node.js version is now 12.0.
- Updated dependencies to newer versions and/or more actively maintained packages.
- In TypeScript, the property
LDEvaluationDetail.reason
now has a type ofLDEvaluationReason | undefined
, which correctly reflects the fact that evaluation reasons may not always be available.
- If the platform local storage mechanism throws an exception (for instance, if file permissions do not allow the data to be saved), the SDK now correctly catches the exception and logs a message about the failure. It will only log this message once during the lifetime of the SDK client.
- Removed the dependency on Winston. You can still tell the SDK to use a Winston logger instance that you have created, just as before, so this change should not affect any applications that are using Winston. But the SDK no longer uses Winston to create a default logger if the application does not specify a logger; instead, it uses the
basicLogger
implementation, which uses the same format as the previous default Winston configuration, so again there should be no visible difference. - Removed
createConsoleLogger
, which is replaced by the more flexiblebasicLogger
. - Removed the type
NonNullableLDEvaluationReason
, which was a side effect ofLDEvaluationDetail.reason
being incorrectly defined before. - Removed all types, properties, and functions that were deprecated as of the last 1.x release.
- Events for the LaunchDarkly debugger are now properly pre-processed to omit private user attributes, as well as enforce only expected top level attributes are sent.
- Events for the LaunchDarkly debugger now include the index of the variation responsible for the evaluation result.
- Updated transitive dependency on the package
url-parse
due to a vulnerability warning.
- The property
LDOptions.inlineUsersInEvents
was not included in the TypeScript definitions.
- Added the
alias
method. This method can be used to associate two user objects for analytics purposes. When invoked, this method will queue a new alias event to be sent to LaunchDarkly. - Added the
autoAliasingOptOut
configuration option. This can be used to control the new automatic aliasing behavior of theidentify
method; by passingautoAliasingOptOut: true
,identify
will not automatically generate alias events.
- The
identify
method will now automatically generate an alias event when switching from an anonymous to a known user. This event associates the two users for analytics purposes as they most likely represent a single person.
- In streaming mode, the SDK now automatically drops and restarts the stream connection if it has received no data from the server within a 5-minute interval. This ensures that if the connection fails in such a way that the SDK cannot detect the failure as an I/O error, it will not hang forever waiting for updates from the phantom connection. The LaunchDarkly streaming service sends a tiny "heartbeat" message at regular intervals less than this timeout, to ensure that the SDK will not drop the connection if it is still usable. This logic exists in most other LaunchDarkly SDKs but was not previously implemented in the Node client-side SDK.
- In TypeScript,
LDEvaluationDetail.reason
is now correctly defined as being nullable. This value isnull
ifLDOptions.evaluationReasons
is false.
- In streaming mode, when connecting to the Relay Proxy rather than directly to the LaunchDarkly streaming service, if the current user was changed twice within a short time it was possible for the SDK to revert to flag values from the previous user.
- The default implementation of logging now uses Winston 3.x rather than Winston 2.x. This does not change the content of the log output, and if you have specified your own custom logger then the SDK still uses that. The only effect is that the SDK no longer has dependencies on Winston 2.x.
- Fixed a bug that could cause extra delays when receiving a large streaming update. The process will still be blocked for some amount of time as the JSON data is being parsed, which is unavoidable in the current architecture, but this bug made it block for longer than necessary.
- The TypeScript declaration for
track()
was missing the optionalmetricValue
parameter.
- Some diagnostic event data was being sent twice, resulting in extra HTTP requests. This did not affect analytics events, so customer data on the dashboard and in data export would still be correct.
- Some users reported an error where the SDK said that the content type of a response was
application/json, application/json; charset=utf8
. It is invalid to have multiple Content-Type values in a response and the LaunchDarkly service does not do this, but an improperly configured proxy/gateway might add such a header. Now the SDK will tolerate a value like this as long as it starts withapplication/json
. - Fixed incorrect usage of
Object.hasOwnProperty
which could have caused an error if a feature flag hadhasOwnProperty
as its flag key.
- At client initialization time, if the initial flag polling request failed, it would cause an unhandled promise rejection unless the application had called
waitForInitialization()
and provided an error handler for the promise that was returned by that method. While that is correct behavior if the application did callwaitForInitialization()
(any promise that might be rejected should have an error handler attached), it is inappropriate if the application did not callwaitForInitialization()
at all-- which is not mandatory, since the application could use events instead, orwaitUntilReady()
, or might simply not care about waiting for initialization. This has been fixed so that no such promise is created until the first time the application callswaitForInitialization()
; subsequent calls to the same method will return the same promise (since initialization can only happen once). - A bug in the event emitter made its behavior unpredictable if an event handler called
on
oroff
while handling an event. This has been fixed so that all event handlers that were defined at the time the event was fired will be called; any changes made will not take effect until the next event.
Note: if you are using the LaunchDarkly Relay Proxy to forward events, update the Relay to version 5.10.0 or later before updating to this Node client-side SDK version.
- The SDK now periodically sends diagnostic data to LaunchDarkly, describing the version and configuration of the SDK, the architecture and version of the runtime platform, and performance statistics. No credentials, hostnames, or other identifiable values are included. This behavior can be disabled with the
diagnosticOptOut
option, or configured withdiagnosticRecordingInterval
.
- When using secure mode in conjunction with streaming mode, if an application specified a new
hash
parameter while changing the current user withidentify()
, the SDK was not using the newhash
value when recomputing the stream URL, causing the stream to fail. (Thanks, andrao!) - Changed some exact version dependencies to "highest compatible" dependencies, to avoid having modules that are also used by the host application loaded twice by NPM. The dependency on
js-sdk-common
is still an exact version dependency so that each release ofnode-client-sdk
has well-defined behavior for that internal code. - Updated comment on
initialize
to clarify the intended singleton usage pattern.
- Removed an unused transitive dependency on
@babel/polyfill
.
- The SDK now specifies a uniquely identifiable request header when sending events to LaunchDarkly to ensure that events are only processed once, even if the SDK sends them two times due to a failed initial attempt.
- Configuration property
eventCapacity
: the maximum number of analytics events (not counting evaluation counters) that can be held at once, to prevent the SDK from consuming unexpected amounts of memory in case an application generates events unusually rapidly. In JavaScript code this would not normally be an issue, since the SDK flushes events every two seconds by default, but you may wish to increase this value if you will intentionally be generating a high volume of custom or identify events. The default value is 100. LDClient.version
property reports the SDK version string programmatically.
- The SDK now logs a warning if any configuration property has an inappropriate type, such as
baseUri:3
orsendEvents:"no"
. For boolean properties, the SDK will still interpret the value in terms of truthiness, which was the previous behavior. For all other types, since there's no such commonly accepted way to coerce the type, it will fall back to the default setting for that property; previously, the behavior was undefined but most such mistakes would have caused the SDK to throw an exception at some later point. - Removed or updated some development dependencies that were causing vulnerability warnings.
- The
samplingInterval
configuration property was deprecated in the code in the previous minor version release, and in the changelog, but the deprecation notice was accidentally omitted from the documentation comments. It is hereby deprecated again.
- A runtime dependency on
typedoc
was mistakenly added in the 1.2.0 release. This has been removed.
- Changed the behavior of the warning message that is logged on failing to establish a streaming connection. Rather than the current behavior where the warning message appears upon each failed attempt, it will now only appear on the first failure in each series of attempts. Also, the message has been changed to mention that retries will occur.
- The
samplingInterval
configuration property is deprecated and will be removed in a future version. The intended use case for thesamplingInterval
feature was to reduce analytics event network usage in high-traffic applications. This feature is being deprecated in favor of summary counters, which are meant to track all events.
- Added support for upcoming LaunchDarkly experimentation features. See
LDClient.track()
. - The
createConsoleLogger()
function now has an optional second parameter for customizing the log prefix.
- Log messages from
createConsoleLogger()
now include the level ("[warn]", "[error]", etc.) and have a prefix of "LD:" by default.
- The SDK now logs a message at
info
level when the stream connection is started or stopped. It also logs a message atwarn
level if it detects that the stream had to be restarted due to a connection failure.
- The SDK failed to restart a streaming connection if it had already been dropped and restarted before. This project adheres to Semantic Versioning.
Beta release, feature-complete. Note that the TLS configuration feature, while it is covered to some degree in unit tests, has not been tested against a real server.