launchdarkly-js-sdk-common 5.0.0-alpha.7 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,8 @@ repo:
6
6
 
7
7
  branches:
8
8
  - name: main
9
- description: 4.x
9
+ description: 5.x
10
+ - name: 4.x
10
11
  - name: 3.x
11
12
 
12
13
  publications:
package/CHANGELOG.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  All notable changes to the `launchdarkly-js-sdk-common` package will be documented in this file. Changes that affect the dependent SDKs such as `launchdarkly-js-client-sdk` should also be logged in those projects, in the next release that uses the updated version of this package. This project adheres to [Semantic Versioning](http://semver.org).
4
4
 
5
+ ## [5.0.0] - 2022-11-30
6
+ This major version release of `js-sdk-common` corresponds to the upcoming releases of the `js-client-sdk` v3 and `react-client-sdk` v3, and cannot be used with earlier SDK versions.
7
+
8
+ ### Added:
9
+ - Replaced users with contexts. A context is a generalized way of referring to the people, services, machines, or other resources that encounter feature flags in your product. All methods which previously operated on `LDUser` now operate on `LDContext`.
10
+
11
+ ### Changed:
12
+ - `LDClient.getUser` has been replaced with `LDClient.getContext`.
13
+ - `privateAttributeNames` has been replaced with `privateAttributes`. Private attributes now allow using attribute references, which allow for marking nodes in nested JSON private.
14
+
15
+ ### Removed:
16
+ - Alias events are no longer supported and the `alias` method has been removed from `LDClient`.
17
+ - Support for the `secondary` attribute has been removed from `LDUser`. If a secondary attribute is included in a context, then it is a normal attribute that can be used in rule evaluation, but it will not affect bucketing.
18
+ - `allowFrequentDuplicateEvents` has been removed from `LDOptions`. This had been deprecated in a previous version. The default behavior is as if this option had been set to true.
19
+ - `autoAliasingOptOut` has been removed from `LDOptions`. This functionality has been superseded by multi-context support.
20
+ - `inlineUsersInEvents` has been removed from `LDOptions`. Changes associated with contexts has removed the needed for this option.
21
+
22
+ ### Deprecated:
23
+ - The `LDUser` object has been deprecated. Support for `LDUser` is maintained to simplify the upgrade process, but it is recommended to use `LDContext` in the shape of either `LDSingleKindContext` or `LDMultiKindContext`.
24
+
5
25
  ## [4.3.2] - 2022-10-20
6
26
  ### Added:
7
27
  - Implemented `jitter` and `backoff` for streaming connections. When a connection fails the retry will start at the `streamReconnectDelay` 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`).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "launchdarkly-js-sdk-common",
3
- "version": "5.0.0-alpha.7",
3
+ "version": "5.0.1",
4
4
  "description": "LaunchDarkly SDK for JavaScript - common code",
5
5
  "author": "LaunchDarkly <team@launchdarkly.com>",
6
6
  "license": "Apache-2.0",
@@ -57,12 +57,12 @@ function InspectorManager(inspectors, logger) {
57
57
  *
58
58
  * @param {string} flagKey The key for the flag.
59
59
  * @param {Object} detail The LDEvaluationDetail for the flag.
60
- * @param {Object} user The LDUser for the flag.
60
+ * @param {Object} context The LDContext for the flag.
61
61
  */
62
- manager.onFlagUsed = (flagKey, detail, user) => {
62
+ manager.onFlagUsed = (flagKey, detail, context) => {
63
63
  if (inspectorsByType[InspectorTypes.flagUsed].length) {
64
64
  onNextTick(() => {
65
- inspectorsByType[InspectorTypes.flagUsed].forEach(inspector => inspector.method(flagKey, detail, user));
65
+ inspectorsByType[InspectorTypes.flagUsed].forEach(inspector => inspector.method(flagKey, detail, context));
66
66
  });
67
67
  }
68
68
  };
@@ -99,16 +99,16 @@ function InspectorManager(inspectors, logger) {
99
99
  };
100
100
 
101
101
  /**
102
- * Notify the registered inspectors that the user identity has changed.
102
+ * Notify the registered inspectors that the context identity has changed.
103
103
  *
104
104
  * The notification itself will be dispatched asynchronously.
105
105
  *
106
- * @param {Object} user The `LDUser` which is now identified.
106
+ * @param {Object} context The `LDContext` which is now identified.
107
107
  */
108
- manager.onIdentityChanged = user => {
108
+ manager.onIdentityChanged = context => {
109
109
  if (inspectorsByType[InspectorTypes.clientIdentityChanged].length) {
110
110
  onNextTick(() => {
111
- inspectorsByType[InspectorTypes.clientIdentityChanged].forEach(inspector => inspector.method(user));
111
+ inspectorsByType[InspectorTypes.clientIdentityChanged].forEach(inspector => inspector.method(context));
112
112
  });
113
113
  }
114
114
  };
@@ -39,16 +39,16 @@ describe('given an inspector with callbacks of every type', () => {
39
39
  {
40
40
  type: 'flag-used',
41
41
  name: 'my-flag-used-inspector',
42
- method: (flagKey, flagDetail, user) => {
43
- eventQueue.add({ type: 'flag-used', flagKey, flagDetail, user });
42
+ method: (flagKey, flagDetail, context) => {
43
+ eventQueue.add({ type: 'flag-used', flagKey, flagDetail, context });
44
44
  },
45
45
  },
46
46
  // 'flag-used registered twice.
47
47
  {
48
48
  type: 'flag-used',
49
49
  name: 'my-other-flag-used-inspector',
50
- method: (flagKey, flagDetail, user) => {
51
- eventQueue.add({ type: 'flag-used', flagKey, flagDetail, user });
50
+ method: (flagKey, flagDetail, context) => {
51
+ eventQueue.add({ type: 'flag-used', flagKey, flagDetail, context });
52
52
  },
53
53
  },
54
54
  {
@@ -75,10 +75,10 @@ describe('given an inspector with callbacks of every type', () => {
75
75
  {
76
76
  type: 'client-identity-changed',
77
77
  name: 'my-identity-inspector',
78
- method: user => {
78
+ method: context => {
79
79
  eventQueue.add({
80
80
  type: 'client-identity-changed',
81
- user,
81
+ context,
82
82
  });
83
83
  },
84
84
  },
@@ -137,7 +137,7 @@ describe('given an inspector with callbacks of every type', () => {
137
137
  kind: 'OFF',
138
138
  },
139
139
  },
140
- user: { key: 'test-key' },
140
+ context: { key: 'test-key' },
141
141
  };
142
142
  const event1 = await eventQueue.take();
143
143
  expect(event1).toMatchObject(expectedEvent);
@@ -180,7 +180,7 @@ describe('given an inspector with callbacks of every type', () => {
180
180
  const event = await eventQueue.take();
181
181
  expect(event).toMatchObject({
182
182
  type: 'client-identity-changed',
183
- user: { key: 'the-key' },
183
+ context: { key: 'the-key' },
184
184
  });
185
185
  });
186
186
  });
@@ -3,7 +3,7 @@ const { respondJson } = require('./mockHttp');
3
3
  const stubPlatform = require('./stubPlatform');
4
4
 
5
5
  const envName = 'UNKNOWN_ENVIRONMENT_ID';
6
- const user = { key: 'user' };
6
+ const context = { key: 'context-key' };
7
7
 
8
8
  describe('given a streaming client with registered inspectors', () => {
9
9
  const eventQueue = new AsyncQueue();
@@ -11,15 +11,15 @@ describe('given a streaming client with registered inspectors', () => {
11
11
  const inspectors = [
12
12
  {
13
13
  type: 'flag-used',
14
- method: (flagKey, flagDetail, user) => {
15
- eventQueue.add({ type: 'flag-used', flagKey, flagDetail, user });
14
+ method: (flagKey, flagDetail, context) => {
15
+ eventQueue.add({ type: 'flag-used', flagKey, flagDetail, context });
16
16
  },
17
17
  },
18
18
  // 'flag-used registered twice.
19
19
  {
20
20
  type: 'flag-used',
21
- method: (flagKey, flagDetail, user) => {
22
- eventQueue.add({ type: 'flag-used', flagKey, flagDetail, user });
21
+ method: (flagKey, flagDetail, context) => {
22
+ eventQueue.add({ type: 'flag-used', flagKey, flagDetail, context });
23
23
  },
24
24
  },
25
25
  {
@@ -43,10 +43,10 @@ describe('given a streaming client with registered inspectors', () => {
43
43
  },
44
44
  {
45
45
  type: 'client-identity-changed',
46
- method: user => {
46
+ method: context => {
47
47
  eventQueue.add({
48
48
  type: 'client-identity-changed',
49
- user,
49
+ context,
50
50
  });
51
51
  },
52
52
  },
@@ -60,7 +60,7 @@ describe('given a streaming client with registered inspectors', () => {
60
60
  const server = platform.testing.http.newServer();
61
61
  server.byDefault(respondJson({}));
62
62
  const config = { streaming: true, baseUrl: server.url, inspectors, sendEvents: false };
63
- client = platform.testing.makeClient(envName, user, config);
63
+ client = platform.testing.makeClient(envName, context, config);
64
64
  await client.waitUntilReady();
65
65
  });
66
66
 
@@ -81,7 +81,7 @@ describe('given a streaming client with registered inspectors', () => {
81
81
  const ident = await eventQueue.take();
82
82
  expect(ident).toMatchObject({
83
83
  type: 'client-identity-changed',
84
- user,
84
+ context,
85
85
  });
86
86
  const flagsEvent = await eventQueue.take();
87
87
  expect(flagsEvent).toMatchObject({
@@ -7,10 +7,10 @@ import PersistentStorage from '../PersistentStorage';
7
7
  import * as utils from '../utils';
8
8
 
9
9
  describe('PersistentFlagStore', () => {
10
- const user = { key: 'user' };
11
- const ident = Identity(user);
10
+ const context = { key: 'context-key', kind: 'user' };
11
+ const ident = Identity(context);
12
12
  const env = 'ENVIRONMENT';
13
- const lsKey = 'ld:' + env + ':' + utils.btoa(JSON.stringify(user));
13
+ const lsKey = 'ld:' + env + ':' + utils.btoa(JSON.stringify(context));
14
14
 
15
15
  it('stores flags', async () => {
16
16
  const platform = stubPlatform.defaults();
@@ -73,7 +73,7 @@ describe('PersistentFlagStore', () => {
73
73
  expect(platform.testing.getLocalStorageImmediately(lsKey)).toBe(undefined);
74
74
  });
75
75
 
76
- it('uses hash, if present, instead of user properties', async () => {
76
+ it('uses hash, if present, instead of context properties', async () => {
77
77
  const platform = stubPlatform.defaults();
78
78
  const storage = PersistentStorage(platform.localStorage, platform.testing.logger);
79
79
  const hash = '12345';
@@ -83,14 +83,14 @@ export function defaults() {
83
83
 
84
84
  eventSourcesCreated,
85
85
 
86
- makeClient: (env, user, options = {}) => {
86
+ makeClient: (env, context, options = {}) => {
87
87
  const config = { logger: p.testing.logger, ...options };
88
88
  // We want to simulate what the platform-specific SDKs will do in their own initialization functions.
89
89
  // They will call the common package's LDClient.initialize() and receive the clientVars object which
90
90
  // contains both the underlying client (in its "client" property) and some internal methods that the
91
91
  // platform-specific SDKs can use to do internal stuff. One of those is start(), which they will
92
92
  // call after doing any other initialization things they may need to do.
93
- const clientVars = LDClient.initialize(env, user, config, p);
93
+ const clientVars = LDClient.initialize(env, context, config, p);
94
94
  clientVars.start();
95
95
  return clientVars.client;
96
96
  },
@@ -66,8 +66,8 @@ describe('utils', () => {
66
66
 
67
67
  describe('chunkEventsForUrl', () => {
68
68
  it('should properly chunk the list of events', () => {
69
- const user = { key: 'foo' };
70
- const event = { kind: 'identify', key: user.key };
69
+ const context = { key: 'foo', kind: 'user' };
70
+ const event = { kind: 'identify', key: context.key };
71
71
  const eventLength = base64URLEncode(JSON.stringify(event)).length;
72
72
  const events = [event, event, event, event, event];
73
73
  const chunks = chunkEventsForUrl(eventLength * 2, events);
@@ -1,6 +1,6 @@
1
1
  const { v1: uuidv1 } = require('uuid');
2
2
  // Note that in the diagnostic events spec, these IDs are to be generated with UUID v4. However,
3
- // in JS we were already using v1 for unique user keys, so to avoid bringing in two packages we
3
+ // in JS we were already using v1 for unique context keys, so to avoid bringing in two packages we
4
4
  // will use v1 here as well.
5
5
 
6
6
  const { baseOptionDefs } = require('./configuration');
package/src/index.js CHANGED
@@ -189,8 +189,8 @@ function initialize(env, context, specifiedOptions, platform, extraOptionDefs) {
189
189
  }
190
190
  }
191
191
 
192
- function onIdentifyChange(user) {
193
- sendIdentifyEvent(user);
192
+ function onIdentifyChange(context) {
193
+ sendIdentifyEvent(context);
194
194
  notifyInspectionIdentityChanged();
195
195
  }
196
196
 
package/typings.d.ts CHANGED
@@ -327,8 +327,7 @@ declare module 'launchdarkly-js-sdk-common' {
327
327
  *
328
328
  * This is a metadata property, rather than an attribute that can be addressed in evaluations:
329
329
  * that is, a rule clause that references the attribute name "privateAttributes", will not use
330
- * this value, but instead will use whatever value (if any) you have set for that name with a
331
- * method such as SetString.
330
+ * this value, but would use a "privateAttributes" attribute set on the context.
332
331
  */
333
332
  privateAttributes?: string[];
334
333
  }
@@ -338,7 +337,7 @@ declare module 'launchdarkly-js-sdk-common' {
338
337
  * parts that compose a multi context. For more information see {@link LDSingleKindContext} and
339
338
  * {@link LDMultiKindContext}.
340
339
  */
341
- interface LDContextCommon {
340
+ export interface LDContextCommon {
342
341
  /**
343
342
  * If true, the context will _not_ appear on the Contexts page in the LaunchDarkly dashboard.
344
343
  */
@@ -387,7 +386,7 @@ declare module 'launchdarkly-js-sdk-common' {
387
386
  * The above context would be a single kind context representing an organization. It has a key
388
387
  * for that organization, and a single attribute 'someAttribute'.
389
388
  */
390
- interface LDSingleKindContext extends LDContextCommon {
389
+ export interface LDSingleKindContext extends LDContextCommon {
391
390
  /**
392
391
  * The kind of the context.
393
392
  */
@@ -425,7 +424,7 @@ declare module 'launchdarkly-js-sdk-common' {
425
424
  * The above multi-context contains both an 'org' and a 'user'. Each with their own key,
426
425
  * attributes, and _meta attributes.
427
426
  */
428
- interface LDMultiKindContext {
427
+ export interface LDMultiKindContext {
429
428
  /**
430
429
  * The kind of the context.
431
430
  */
@@ -556,7 +555,7 @@ declare module 'launchdarkly-js-sdk-common' {
556
555
  * Describes the reason that a flag evaluation produced a particular value. This is
557
556
  * part of the {@link LDEvaluationDetail} object returned by {@link LDClient.variationDetail]].
558
557
  */
559
- interface LDEvaluationReason {
558
+ export interface LDEvaluationReason {
560
559
  /**
561
560
  * The general category of the reason:
562
561
  *
@@ -997,7 +996,7 @@ declare module 'launchdarkly-js-sdk-common' {
997
996
  * This interface should not be used by the application to access flags for the purpose of controlling application
998
997
  * flow. It is intended for monitoring, analytics, or debugging purposes.
999
998
  */
1000
- interface LDInspectionFlagUsedHandler {
999
+ export interface LDInspectionFlagUsedHandler {
1001
1000
  type: 'flag-used',
1002
1001
 
1003
1002
  /**
@@ -1024,7 +1023,7 @@ declare module 'launchdarkly-js-sdk-common' {
1024
1023
  * This interface should not be used by the application to access flags for the purpose of controlling application
1025
1024
  * flow. It is intended for monitoring, analytics, or debugging purposes.
1026
1025
  */
1027
- interface LDInspectionFlagDetailsChangedHandler {
1026
+ export interface LDInspectionFlagDetailsChangedHandler {
1028
1027
  type: 'flag-details-changed',
1029
1028
 
1030
1029
  /**
@@ -1050,7 +1049,7 @@ declare module 'launchdarkly-js-sdk-common' {
1050
1049
  * This interface should not be used by the application to access flags for the purpose of controlling application
1051
1050
  * flow. It is intended for monitoring, analytics, or debugging purposes.
1052
1051
  */
1053
- interface LDInspectionFlagDetailChangedHandler {
1052
+ export interface LDInspectionFlagDetailChangedHandler {
1054
1053
  type: 'flag-detail-changed',
1055
1054
 
1056
1055
  /**
@@ -1073,7 +1072,7 @@ declare module 'launchdarkly-js-sdk-common' {
1073
1072
  * This interface should not be used by the application to access flags for the purpose of controlling application
1074
1073
  * flow. It is intended for monitoring, analytics, or debugging purposes.
1075
1074
  */
1076
- interface LDInspectionIdentifyHandler {
1075
+ export interface LDInspectionIdentifyHandler {
1077
1076
  type: 'client-identity-changed',
1078
1077
 
1079
1078
  /**
@@ -1087,6 +1086,6 @@ declare module 'launchdarkly-js-sdk-common' {
1087
1086
  method: (context: LDContext) => void;
1088
1087
  }
1089
1088
 
1090
- type LDInspection = LDInspectionFlagUsedHandler | LDInspectionFlagDetailsChangedHandler
1089
+ export type LDInspection = LDInspectionFlagUsedHandler | LDInspectionFlagDetailsChangedHandler
1091
1090
  | LDInspectionFlagDetailChangedHandler | LDInspectionIdentifyHandler;
1092
1091
  }