Skip to content

Commit 4fdbdbd

Browse files
authored
Merge branch 'launchdarkly:main' into mzafir/react-native-jest-mock
2 parents beef6b0 + ec4377c commit 4fdbdbd

File tree

17 files changed

+1190
-97
lines changed

17 files changed

+1190
-97
lines changed

packages/sdk/browser/__tests__/compat/LDClientCompatImpl.test.ts

Lines changed: 524 additions & 0 deletions
Large diffs are not rendered by default.

packages/sdk/browser/contract-tests/entity/src/ClientEntity.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ function makeSdkConfig(options: SDKConfigParams, tag: string) {
1818
const cf: LDOptions = {
1919
withReasons: options.clientSide.evaluationReasons,
2020
logger: makeLogger(`${tag}.sdk`),
21-
// useReport: options.clientSide.useReport,
21+
useReport: options.clientSide.useReport,
2222
};
2323

2424
if (options.serviceEndpoints) {

packages/sdk/browser/contract-tests/entity/src/makeLogger.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ import { LDLogger } from '@launchdarkly/js-client-sdk';
22

33
export function makeLogger(tag: string): LDLogger {
44
return {
5-
debug(message, ...args: any[]) {
5+
debug(message: any, ...args: any[]) {
66
// eslint-disable-next-line no-console
77
console.debug(`${new Date().toISOString()} [${tag}]: ${message}`, ...args);
88
},
9-
info(message, ...args: any[]) {
9+
info(message: any, ...args: any[]) {
1010
// eslint-disable-next-line no-console
1111
console.info(`${new Date().toISOString()} [${tag}]: ${message}`, ...args);
1212
},
13-
warn(message, ...args: any[]) {
13+
warn(message: any, ...args: any[]) {
1414
// eslint-disable-next-line no-console
1515
console.warn(`${new Date().toISOString()} [${tag}]: ${message}`, ...args);
1616
},
17-
error(message, ...args: any[]) {
17+
error(message: any, ...args: any[]) {
1818
// eslint-disable-next-line no-console
1919
console.error(`${new Date().toISOString()} [${tag}]: ${message}`, ...args);
2020
},

packages/sdk/browser/contract-tests/suppressions.txt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,3 @@ streaming/requests/URL path is computed correctly/no environment filter/base URI
44
streaming/requests/context properties/single kind minimal/REPORT
55
streaming/requests/context properties/single kind with all attributes/REPORT
66
streaming/requests/context properties/multi-kind/REPORT
7-
polling/requests/method and headers/REPORT/http
8-
polling/requests/URL path is computed correctly/no environment filter/base URI has no trailing slash/REPORT
9-
polling/requests/URL path is computed correctly/no environment filter/base URI has a trailing slash/REPORT
10-
polling/requests/context properties/single kind minimal/REPORT
11-
polling/requests/context properties/single kind with all attributes/REPORT
12-
polling/requests/context properties/multi-kind/REPORT

packages/sdk/browser/package.json

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,38 @@
1616
"feature management",
1717
"sdk"
1818
],
19+
"type": "module",
20+
"main": "./dist/index.cjs",
21+
"module": "./dist/index.js",
22+
"types": "./dist/index.d.ts",
1923
"exports": {
20-
"types": "./dist/src/index.d.ts",
21-
"require": "./dist/index.cjs.js",
22-
"import": "./dist/index.es.js"
24+
".": {
25+
"require": {
26+
"types": "./dist/index.d.cts",
27+
"require": "./dist/index.cjs"
28+
},
29+
"import": {
30+
"types": "./dist/index.d.ts",
31+
"import": "./dist/index.js"
32+
}
33+
},
34+
"./compat": {
35+
"require": {
36+
"types": "./dist/compat.d.cts",
37+
"require": "./dist/compat.cjs"
38+
},
39+
"import": {
40+
"types": "./dist/compat.d.ts",
41+
"import": "./dist/compat.js"
42+
}
43+
}
2344
},
24-
"type": "module",
2545
"files": [
2646
"dist"
2747
],
2848
"scripts": {
2949
"clean": "rimraf dist",
30-
"build": "tsc --noEmit && rollup -c rollup.config.js",
50+
"build": "tsup",
3151
"lint": "eslint . --ext .ts,.tsx",
3252
"prettier": "prettier --write '**/*.@(js|ts|tsx|json|css)' --ignore-path ../../../.prettierignore",
3353
"test": "npx jest --runInBand",
@@ -39,11 +59,6 @@
3959
},
4060
"devDependencies": {
4161
"@jest/globals": "^29.7.0",
42-
"@rollup/plugin-commonjs": "^25.0.0",
43-
"@rollup/plugin-json": "^6.1.0",
44-
"@rollup/plugin-node-resolve": "^15.0.2",
45-
"@rollup/plugin-terser": "^0.4.3",
46-
"@rollup/plugin-typescript": "^11.1.1",
4762
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
4863
"@types/jest": "^29.5.11",
4964
"@typescript-eslint/eslint-plugin": "^6.20.0",
@@ -59,9 +74,8 @@
5974
"jest-environment-jsdom": "^29.7.0",
6075
"prettier": "^3.0.0",
6176
"rimraf": "^5.0.5",
62-
"rollup": "^3.23.0",
63-
"rollup-plugin-visualizer": "^5.12.0",
6477
"ts-jest": "^29.1.1",
78+
"tsup": "^8.3.5",
6579
"typedoc": "0.25.0",
6680
"typescript": "^5.5.3"
6781
}

packages/sdk/browser/rollup.config.js

Lines changed: 0 additions & 58 deletions
This file was deleted.
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import { LDContext, LDFlagSet } from '@launchdarkly/js-client-sdk-common';
2+
3+
import { LDClient as LDCLientBrowser } from '../BrowserClient';
4+
5+
/**
6+
* Compatibility interface. This interface extends the base LDCLient interface with functions
7+
* that improve backwards compatibility.
8+
*
9+
* If starting a new project please import the root package instead of `/compat`.
10+
*
11+
* In the `[email protected]` package a number of functions had the return typings
12+
* incorrect. Any function which optionally returned a promise based on a callback had incorrect
13+
* typings. Those have been corrected in this implementation.
14+
*/
15+
export interface LDClient extends Omit<LDCLientBrowser, 'close' | 'flush' | 'identify'> {
16+
/**
17+
* Identifies a context to LaunchDarkly.
18+
*
19+
* Unlike the server-side SDKs, the client-side JavaScript SDKs maintain a current context state,
20+
* which is set at initialization time. You only need to call `identify()` if the context has changed
21+
* since then.
22+
*
23+
* Changing the current context also causes all feature flag values to be reloaded. Until that has
24+
* finished, calls to {@link variation} will still return flag values for the previous context. You can
25+
* use a callback or a Promise to determine when the new flag values are available.
26+
*
27+
* @param context
28+
* The context properties. Must contain at least the `key` property.
29+
* @param hash
30+
* The signed context key if you are using [Secure Mode](https://docs.launchdarkly.com/sdk/features/secure-mode#configuring-secure-mode-in-the-javascript-client-side-sdk).
31+
* @param onDone
32+
* A function which will be called as soon as the flag values for the new context are available,
33+
* with two parameters: an error value (if any), and an {@link LDFlagSet} containing the new values
34+
* (which can also be obtained by calling {@link variation}). If the callback is omitted, you will
35+
* receive a Promise instead.
36+
* @returns
37+
* If you provided a callback, then nothing. Otherwise, a Promise which resolve once the flag
38+
* values for the new context are available, providing an {@link LDFlagSet} containing the new values
39+
* (which can also be obtained by calling {@link variation}).
40+
*/
41+
identify(
42+
context: LDContext,
43+
hash?: string,
44+
onDone?: (err: Error | null, flags: LDFlagSet | null) => void,
45+
): Promise<LDFlagSet> | undefined;
46+
47+
/**
48+
* Returns a Promise that tracks the client's initialization state.
49+
*
50+
* The Promise will be resolved if the client successfully initializes, or rejected if client
51+
* initialization has irrevocably failed (for instance, if it detects that the SDK key is invalid).
52+
*
53+
* ```
54+
* // using async/await
55+
* try {
56+
* await client.waitForInitialization(5);
57+
* doSomethingWithSuccessfullyInitializedClient();
58+
* } catch (err) {
59+
* doSomethingForFailedStartup(err);
60+
* }
61+
* ```
62+
*
63+
* It is important that you handle the rejection case; otherwise it will become an unhandled Promise
64+
* rejection, which is a serious error on some platforms. The Promise is not created unless you
65+
* request it, so if you never call `waitForInitialization()` then you do not have to worry about
66+
* unhandled rejections.
67+
*
68+
* Note that you can also use event listeners ({@link on}) for the same purpose: the event `"initialized"`
69+
* indicates success, and `"failed"` indicates failure.
70+
*
71+
* @param timeout
72+
* The amount of time, in seconds, to wait for initialization before rejecting the promise.
73+
* Using a large timeout is not recommended. If you use a large timeout and await it, then
74+
* any network delays will cause your application to wait a long time before
75+
* continuing execution.
76+
*
77+
* If no timeout is specified, then the returned promise will only be resolved when the client
78+
* successfully initializes or initialization fails.
79+
*
80+
* @returns
81+
* A Promise that will be resolved if the client initializes successfully, or rejected if it
82+
* fails or the specified timeout elapses.
83+
*/
84+
waitForInitialization(timeout?: number): Promise<void>;
85+
86+
/**
87+
* Returns a Promise that tracks the client's initialization state.
88+
*
89+
* The returned Promise will be resolved once the client has either successfully initialized
90+
* or failed to initialize (e.g. due to an invalid environment key or a server error). It will
91+
* never be rejected.
92+
*
93+
* ```
94+
* // using async/await
95+
* await client.waitUntilReady();
96+
* doSomethingWithClient();
97+
* ```
98+
*
99+
* If you want to distinguish between these success and failure conditions, use
100+
* {@link waitForInitialization} instead.
101+
*
102+
* If you prefer to use event listeners ({@link on}) rather than Promises, you can listen on the
103+
* client for a `"ready"` event, which will be fired in either case.
104+
*
105+
* @returns
106+
* A Promise that will be resolved once the client is no longer trying to initialize.
107+
* @deprecated Please use {@link waitForInitialization} instead. This method will always
108+
* cause a warning to be logged because it is implemented via waitForInitialization.
109+
*/
110+
waitUntilReady(): Promise<void>;
111+
112+
/**
113+
* Shuts down the client and releases its resources, after delivering any pending analytics
114+
* events.
115+
*
116+
* @param onDone
117+
* A function which will be called when the operation completes. If omitted, you
118+
* will receive a Promise instead.
119+
*
120+
* @returns
121+
* If you provided a callback, then nothing. Otherwise, a Promise which resolves once
122+
* closing is finished. It will never be rejected.
123+
*/
124+
close(onDone?: () => void): Promise<void> | undefined;
125+
126+
/**
127+
* Flushes all pending analytics events.
128+
*
129+
* Normally, batches of events are delivered in the background at intervals determined by the
130+
* `flushInterval` property of {@link LDOptions}. Calling `flush()` triggers an immediate delivery.
131+
*
132+
* @param onDone
133+
* A function which will be called when the flush completes. If omitted, you
134+
* will receive a Promise instead.
135+
*
136+
* @returns
137+
* If you provided a callback, then nothing. Otherwise, a Promise which resolves once
138+
* flushing is finished. Note that the Promise will be rejected if the HTTP request
139+
* fails, so be sure to attach a rejection handler to it.
140+
*/
141+
flush(onDone?: () => void): Promise<void> | undefined;
142+
}

0 commit comments

Comments
 (0)