@launchdarkly/js-server-sdk-common
Advanced tools
Comparing version 2.3.0 to 2.4.0
@@ -11,2 +11,9 @@ # Changelog | ||
## [2.4.0](https://github.com/launchdarkly/js-core/compare/js-server-sdk-common-v2.3.0...js-server-sdk-common-v2.4.0) (2024-04-16) | ||
### Features | ||
* Add support for optional timeout for waitForInitialization. ([#437](https://github.com/launchdarkly/js-core/issues/437)) ([c6032b3](https://github.com/launchdarkly/js-core/commit/c6032b3dd80421ff42aefd729442d18cd27b16e4)) | ||
## [2.3.0](https://github.com/launchdarkly/js-core/compare/js-server-sdk-common-v2.2.4...js-server-sdk-common-v2.3.0) (2024-04-10) | ||
@@ -13,0 +20,0 @@ |
@@ -7,2 +7,3 @@ export * from './data'; | ||
export * from './subsystems/LDFeatureStore'; | ||
export * from './LDWaitForInitializationOptions'; | ||
export * as integrations from './integrations'; | ||
@@ -9,0 +10,0 @@ export * as interfaces from './interfaces'; |
@@ -24,2 +24,3 @@ "use strict"; | ||
__exportStar(require("./subsystems/LDFeatureStore"), exports); | ||
__exportStar(require("./LDWaitForInitializationOptions"), exports); | ||
// These are items that should be less frequently used, and therefore they | ||
@@ -26,0 +27,0 @@ // are namespaced to reduce clutter amongst the top level exports. |
@@ -7,2 +7,3 @@ import { LDContext, LDEvaluationDetail, LDEvaluationDetailTyped, LDFlagValue } from '@launchdarkly/js-sdk-common'; | ||
import { Hook } from './integrations/Hook'; | ||
import { LDWaitForInitializationOptions } from './LDWaitForInitializationOptions'; | ||
/** | ||
@@ -41,12 +42,20 @@ * The LaunchDarkly SDK client object. | ||
* | ||
* There is no built-in timeout for this method. If you want your code to stop waiting on the | ||
* Promise after some amount of time, you could use | ||
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race|`Promise.race()`} | ||
* or one of the several NPM helper packages that provides a standard mechanism for this. | ||
* This method takes an optional parameters which include a timeout. The timeout controls how long | ||
* a specific call to waitForInitialization will wait before rejecting its promise. If a | ||
* subsequent call is made to waitForInitialization with a timeout, then it will again wait up to | ||
* that maximum time. | ||
* | ||
* Regardless of whether you continue to wait, the SDK will still retry all connection failures | ||
* indefinitely unless it gets an unrecoverable error as described above. | ||
* | ||
* Waiting indefinitely, or depending only on the "ready" or "failed" events can result in an | ||
* application waiting indefinitely. It is recommended to use a timeout which is reasonable | ||
* for your application. | ||
* | ||
* @param options Options which control the behavior of `waitForInitialization`. | ||
* | ||
* @returns | ||
* A Promise that will be resolved if the client initializes successfully, or rejected if it | ||
* fails. If successful, the result is the same client object. | ||
* A Promise that will be resolved if the client initializes successfully, or rejected if it | ||
* fails. If successful, the result is the same client object. It is not recommended to use the | ||
* returned client object. It will be removed in a future version. | ||
* | ||
@@ -56,6 +65,6 @@ * @example | ||
* ```javascript | ||
* client.waitForInitialization().then(() => { | ||
* client.waitForInitialization({timeoutSeconds: 10}).then(() => { | ||
* // do whatever is appropriate if initialization has succeeded | ||
* }).catch(err => { | ||
* // do whatever is appropriate if initialization has failed | ||
* // do whatever is appropriate if initialization has failed or timed out | ||
* }) | ||
@@ -68,10 +77,10 @@ * ``` | ||
* try { | ||
* await client.waitForInitialization(); | ||
* await client.waitForInitialization({timeoutSeconds: 10}); | ||
* // do whatever is appropriate if initialization has succeeded | ||
* } catch (err) { | ||
* // do whatever is appropriate if initialization has failed | ||
* // do whatever is appropriate if initialization has failed or timed out | ||
* } | ||
* ``` | ||
*/ | ||
waitForInitialization(): Promise<LDClient>; | ||
waitForInitialization(options?: LDWaitForInitializationOptions): Promise<LDClient>; | ||
/** | ||
@@ -78,0 +87,0 @@ * Determines the variation of a feature flag for a context. |
import { internal, LDContext, LDEvaluationDetail, LDEvaluationDetailTyped, Platform } from '@launchdarkly/js-sdk-common'; | ||
import { LDClient, LDFlagsState, LDFlagsStateOptions, LDMigrationOpEvent, LDMigrationStage, LDMigrationVariation, LDOptions } from './api'; | ||
import { Hook } from './api/integrations/Hook'; | ||
import { LDWaitForInitializationOptions } from './api/LDWaitForInitializationOptions'; | ||
import BigSegmentStoreStatusProvider from './BigSegmentStatusProviderImpl'; | ||
@@ -47,3 +48,3 @@ export interface LDClientCallbacks { | ||
initialized(): boolean; | ||
waitForInitialization(): Promise<LDClient>; | ||
waitForInitialization(options?: LDWaitForInitializationOptions): Promise<LDClient>; | ||
variation(key: string, context: LDContext, defaultValue: any, callback?: (err: any, res: any) => void): Promise<any>; | ||
@@ -76,3 +77,16 @@ variationDetail(key: string, context: LDContext, defaultValue: any, callback?: (err: any, res: LDEvaluationDetail) => void): Promise<LDEvaluationDetail>; | ||
private initSuccess; | ||
/** | ||
* Apply a timeout promise to a base promise. This is for use with waitForInitialization. | ||
* Currently it returns a LDClient. In the future it should return a status. | ||
* | ||
* The client isn't always the expected type of the consumer. It returns an LDClient interface | ||
* which is less capable than, for example, the node client interface. | ||
* | ||
* @param basePromise The promise to race against a timeout. | ||
* @param timeout The timeout in seconds. | ||
* @param logger A logger to log when the timeout expires. | ||
* @returns | ||
*/ | ||
private clientWithTimeout; | ||
} | ||
//# sourceMappingURL=LDClientImpl.d.ts.map |
@@ -31,2 +31,3 @@ "use strict"; | ||
})(InitState || (InitState = {})); | ||
const HIGH_TIMEOUT_THRESHOLD = 60; | ||
const BOOL_VARIATION_METHOD_NAME = 'LDClient.boolVariation'; | ||
@@ -115,3 +116,3 @@ const NUMBER_VARIATION_METHOD_NAME = 'LDClient.numberVariation'; | ||
} | ||
waitForInitialization() { | ||
waitForInitialization(options) { | ||
// An initialization promise is only created if someone is going to use that promise. | ||
@@ -121,5 +122,20 @@ // If we always created an initialization promise, and there was no call waitForInitialization | ||
// rejection. | ||
var _a, _b; | ||
// If there is no update processor, then there is functionally no initialization | ||
// so it is fine not to wait. | ||
if ((options === null || options === void 0 ? void 0 : options.timeout) === undefined && this.updateProcessor !== undefined) { | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn('The waitForInitialization function was called without a timeout specified.' + | ||
' In a future version a default timeout will be applied.'); | ||
} | ||
if ((options === null || options === void 0 ? void 0 : options.timeout) !== undefined && | ||
(options === null || options === void 0 ? void 0 : options.timeout) > HIGH_TIMEOUT_THRESHOLD && | ||
this.updateProcessor !== undefined) { | ||
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.warn('The waitForInitialization function was called with a timeout greater than ' + | ||
`${HIGH_TIMEOUT_THRESHOLD} seconds. We recommend a timeout of less than ` + | ||
`${HIGH_TIMEOUT_THRESHOLD} seconds.`); | ||
} | ||
// Initialization promise was created by a previous call to waitForInitialization. | ||
if (this.initializedPromise) { | ||
return this.initializedPromise; | ||
// This promise may already be resolved/rejected, but it doesn't hurt to wrap it in a timeout. | ||
return this.clientWithTimeout(this.initializedPromise, options === null || options === void 0 ? void 0 : options.timeout, this.logger); | ||
} | ||
@@ -130,2 +146,3 @@ // Initialization completed before waitForInitialization was called, so we have completed | ||
this.initializedPromise = Promise.resolve(this); | ||
// Already initialized, no need to timeout. | ||
return this.initializedPromise; | ||
@@ -136,2 +153,3 @@ } | ||
if (this.initState === InitState.Failed) { | ||
// Already failed, no need to timeout. | ||
this.initializedPromise = Promise.reject(this.rejectionReason); | ||
@@ -146,3 +164,3 @@ return this.initializedPromise; | ||
} | ||
return this.initializedPromise; | ||
return this.clientWithTimeout(this.initializedPromise, options === null || options === void 0 ? void 0 : options.timeout, this.logger); | ||
} | ||
@@ -463,4 +481,28 @@ variation(key, context, defaultValue, callback) { | ||
} | ||
/** | ||
* Apply a timeout promise to a base promise. This is for use with waitForInitialization. | ||
* Currently it returns a LDClient. In the future it should return a status. | ||
* | ||
* The client isn't always the expected type of the consumer. It returns an LDClient interface | ||
* which is less capable than, for example, the node client interface. | ||
* | ||
* @param basePromise The promise to race against a timeout. | ||
* @param timeout The timeout in seconds. | ||
* @param logger A logger to log when the timeout expires. | ||
* @returns | ||
*/ | ||
clientWithTimeout(basePromise, timeout, logger) { | ||
if (timeout) { | ||
const timeoutPromise = (0, js_sdk_common_1.timedPromise)(timeout, 'waitForInitialization'); | ||
return Promise.race([basePromise, timeoutPromise.then(() => this)]).catch((reason) => { | ||
if (reason instanceof js_sdk_common_1.LDTimeoutError) { | ||
logger === null || logger === void 0 ? void 0 : logger.error(reason.message); | ||
} | ||
throw reason; | ||
}); | ||
} | ||
return basePromise; | ||
} | ||
} | ||
exports.default = LDClientImpl; | ||
//# sourceMappingURL=LDClientImpl.js.map |
{ | ||
"name": "@launchdarkly/js-server-sdk-common", | ||
"version": "2.3.0", | ||
"version": "2.4.0", | ||
"type": "commonjs", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
617300
444
8622