@launchdarkly/js-client-sdk-common 1.2.0 → 1.3.0

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.
Files changed (87) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/LDClientImpl.d.ts +40 -32
  3. package/dist/LDClientImpl.d.ts.map +1 -1
  4. package/dist/LDClientImpl.js +179 -127
  5. package/dist/LDClientImpl.js.map +1 -1
  6. package/dist/api/ConnectionMode.d.ts +3 -1
  7. package/dist/api/ConnectionMode.d.ts.map +1 -1
  8. package/dist/api/LDClient.d.ts +1 -1
  9. package/dist/api/LDClient.d.ts.map +1 -1
  10. package/dist/api/LDOptions.d.ts +13 -0
  11. package/dist/api/LDOptions.d.ts.map +1 -1
  12. package/dist/configuration/Configuration.d.ts +2 -1
  13. package/dist/configuration/Configuration.d.ts.map +1 -1
  14. package/dist/configuration/Configuration.js +3 -1
  15. package/dist/configuration/Configuration.js.map +1 -1
  16. package/dist/configuration/validators.d.ts.map +1 -1
  17. package/dist/configuration/validators.js +4 -2
  18. package/dist/configuration/validators.js.map +1 -1
  19. package/dist/context/addAutoEnv.d.ts.map +1 -0
  20. package/dist/{utils → context}/addAutoEnv.js +4 -2
  21. package/dist/context/addAutoEnv.js.map +1 -0
  22. package/dist/{utils → context}/ensureKey.d.ts +1 -2
  23. package/dist/context/ensureKey.d.ts.map +1 -0
  24. package/dist/{utils → context}/ensureKey.js +6 -3
  25. package/dist/context/ensureKey.js.map +1 -0
  26. package/dist/flag-manager/ContextIndex.d.ts +39 -0
  27. package/dist/flag-manager/ContextIndex.d.ts.map +1 -0
  28. package/dist/flag-manager/ContextIndex.js +64 -0
  29. package/dist/flag-manager/ContextIndex.js.map +1 -0
  30. package/dist/flag-manager/FlagManager.d.ts +58 -0
  31. package/dist/flag-manager/FlagManager.d.ts.map +1 -0
  32. package/dist/flag-manager/FlagManager.js +74 -0
  33. package/dist/flag-manager/FlagManager.js.map +1 -0
  34. package/dist/flag-manager/FlagPersistence.d.ts +42 -0
  35. package/dist/flag-manager/FlagPersistence.d.ts.map +1 -0
  36. package/dist/flag-manager/FlagPersistence.js +120 -0
  37. package/dist/flag-manager/FlagPersistence.js.map +1 -0
  38. package/dist/flag-manager/FlagStore.d.ts +29 -0
  39. package/dist/flag-manager/FlagStore.d.ts.map +1 -0
  40. package/dist/flag-manager/FlagStore.js +28 -0
  41. package/dist/flag-manager/FlagStore.js.map +1 -0
  42. package/dist/flag-manager/FlagUpdater.d.ts +39 -0
  43. package/dist/flag-manager/FlagUpdater.d.ts.map +1 -0
  44. package/dist/flag-manager/FlagUpdater.js +69 -0
  45. package/dist/flag-manager/FlagUpdater.js.map +1 -0
  46. package/dist/flag-manager/ItemDescriptor.d.ts +10 -0
  47. package/dist/flag-manager/ItemDescriptor.d.ts.map +1 -0
  48. package/dist/flag-manager/ItemDescriptor.js +3 -0
  49. package/dist/flag-manager/ItemDescriptor.js.map +1 -0
  50. package/dist/flag-manager/calculateChangedKeys.d.ts +6 -0
  51. package/dist/flag-manager/calculateChangedKeys.d.ts.map +1 -0
  52. package/dist/flag-manager/calculateChangedKeys.js +22 -0
  53. package/dist/flag-manager/calculateChangedKeys.js.map +1 -0
  54. package/dist/polling/PollingProcessor.d.ts +3 -0
  55. package/dist/polling/PollingProcessor.d.ts.map +1 -0
  56. package/dist/polling/PollingProcessor.js +79 -0
  57. package/dist/polling/PollingProcessor.js.map +1 -0
  58. package/dist/polling/Requestor.d.ts +6 -0
  59. package/dist/polling/Requestor.d.ts.map +1 -0
  60. package/dist/polling/Requestor.js +50 -0
  61. package/dist/polling/Requestor.js.map +1 -0
  62. package/dist/storage/getOrGenerateKey.d.ts +11 -0
  63. package/dist/storage/getOrGenerateKey.d.ts.map +1 -0
  64. package/dist/storage/getOrGenerateKey.js +21 -0
  65. package/dist/storage/getOrGenerateKey.js.map +1 -0
  66. package/dist/storage/namespaceUtils.d.ts +20 -0
  67. package/dist/storage/namespaceUtils.d.ts.map +1 -0
  68. package/dist/storage/namespaceUtils.js +61 -0
  69. package/dist/storage/namespaceUtils.js.map +1 -0
  70. package/package.json +2 -2
  71. package/dist/utils/addAutoEnv.d.ts.map +0 -1
  72. package/dist/utils/addAutoEnv.js.map +0 -1
  73. package/dist/utils/calculateFlagChanges.d.ts +0 -3
  74. package/dist/utils/calculateFlagChanges.d.ts.map +0 -1
  75. package/dist/utils/calculateFlagChanges.js +0 -23
  76. package/dist/utils/calculateFlagChanges.js.map +0 -1
  77. package/dist/utils/ensureKey.d.ts.map +0 -1
  78. package/dist/utils/ensureKey.js.map +0 -1
  79. package/dist/utils/getOrGenerateKey.d.ts +0 -5
  80. package/dist/utils/getOrGenerateKey.d.ts.map +0 -1
  81. package/dist/utils/getOrGenerateKey.js +0 -29
  82. package/dist/utils/getOrGenerateKey.js.map +0 -1
  83. package/dist/utils/index.d.ts +0 -5
  84. package/dist/utils/index.d.ts.map +0 -1
  85. package/dist/utils/index.js +0 -10
  86. package/dist/utils/index.js.map +0 -1
  87. /package/dist/{utils → context}/addAutoEnv.d.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.3.0](https://github.com/launchdarkly/js-core/compare/js-client-sdk-common-v1.2.0...js-client-sdk-common-v1.3.0) (2024-08-12)
4
+
5
+
6
+ ### Features
7
+
8
+ * Add connection mananger. ([#522](https://github.com/launchdarkly/js-core/issues/522)) ([5bf8b16](https://github.com/launchdarkly/js-core/commit/5bf8b16e26e7d8cbbd18524f1c13f773de457b82))
9
+ * Implement polling support. ([#524](https://github.com/launchdarkly/js-core/issues/524)) ([a99048e](https://github.com/launchdarkly/js-core/commit/a99048e0cebaafd536f79114c4727524b8f7357d))
10
+ * Refactor application state handling. ([#523](https://github.com/launchdarkly/js-core/issues/523)) ([f5b81e6](https://github.com/launchdarkly/js-core/commit/f5b81e6fc571dc9d97a18d07f382c77cd938fd65))
11
+ * refactors the implementation of context caching. You can now s… ([#531](https://github.com/launchdarkly/js-core/issues/531)) ([8ab2ee4](https://github.com/launchdarkly/js-core/commit/8ab2ee425a35350a4f1c50e608c39fa3527da513))
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * Fix field visibility. ([#530](https://github.com/launchdarkly/js-core/issues/530)) ([21fb18b](https://github.com/launchdarkly/js-core/commit/21fb18b40139583b44a4185fb689b043547641ab))
17
+
18
+
19
+ ### Dependencies
20
+
21
+ * The following workspace dependencies were updated
22
+ * dependencies
23
+ * @launchdarkly/js-sdk-common bumped from 2.5.0 to 2.6.0
24
+
3
25
  ## [1.2.0](https://github.com/launchdarkly/js-core/compare/js-client-sdk-common-v1.1.5...js-client-sdk-common-v1.2.0) (2024-07-31)
4
26
 
5
27
 
@@ -2,24 +2,27 @@ import { AutoEnvAttributes, internal, LDContext, LDEvaluationDetail, LDEvaluatio
2
2
  import { ConnectionMode, LDClient, type LDOptions } from './api';
3
3
  import { EventName } from './api/LDEmitter';
4
4
  import { LDIdentifyOptions } from './api/LDIdentifyOptions';
5
- import Configuration from './configuration';
6
5
  export default class LDClientImpl implements LDClient {
7
6
  readonly sdkKey: string;
8
7
  readonly autoEnvAttributes: AutoEnvAttributes;
9
8
  readonly platform: Platform;
10
- config: Configuration;
11
- context?: LDContext;
12
- diagnosticsManager?: internal.DiagnosticsManager;
13
- eventProcessor?: internal.EventProcessor;
14
- identifyTimeout: number;
15
- logger: LDLogger;
16
- streamer?: internal.StreamingProcessor;
17
- readonly highTimeoutThreshold: number;
9
+ private readonly config;
10
+ private uncheckedContext?;
11
+ private checkedContext?;
12
+ private readonly diagnosticsManager?;
13
+ private eventProcessor?;
14
+ private identifyTimeout;
15
+ readonly logger: LDLogger;
16
+ private updateProcessor?;
17
+ private readonly highTimeoutThreshold;
18
18
  private eventFactoryDefault;
19
19
  private eventFactoryWithReasons;
20
20
  private emitter;
21
- private flags;
21
+ private flagManager;
22
22
  private readonly clientContext;
23
+ private eventSendingEnabled;
24
+ private networkAvailable;
25
+ private connectionMode;
23
26
  /**
24
27
  * Creates the client object synchronously. No async, no network calls.
25
28
  */
@@ -44,20 +47,23 @@ export default class LDClientImpl implements LDClient {
44
47
  getContext(): LDContext | undefined;
45
48
  private createStreamListeners;
46
49
  /**
47
- * Generates the url path for streamer.
50
+ * Generates the url path for streaming.
48
51
  *
49
- * For mobile key: /meval/${base64-encoded-context}
50
- * For clientSideId: /eval/${envId}/${base64-encoded-context}
51
- *
52
- * the path.
53
- *
54
- * @protected This function must be overridden in subclasses for streamer
52
+ * @protected This function must be overridden in subclasses for streaming
55
53
  * to work.
56
54
  * @param _context The LDContext object
57
55
  */
58
56
  protected createStreamUriPath(_context: LDContext): string;
57
+ /**
58
+ * Generates the url path for polling.
59
+ * @param _context
60
+ *
61
+ * @protected This function must be overridden in subclasses for polling
62
+ * to work.
63
+ * @param _context The LDContext object
64
+ */
65
+ protected createPollUriPath(_context: LDContext): string;
59
66
  private createIdentifyPromise;
60
- private getFlagsFromStorage;
61
67
  /**
62
68
  * Identifies a context to LaunchDarkly. See {@link LDClient.identify}.
63
69
  *
@@ -74,20 +80,8 @@ export default class LDClientImpl implements LDClient {
74
80
  * 3. A network error is encountered during initialization.
75
81
  */
76
82
  identify(pristineContext: LDContext, identifyOptions?: LDIdentifyOptions): Promise<void>;
77
- /**
78
- * Performs common tasks when resolving the identify promise:
79
- * - resolve the promise
80
- * - update in memory context
81
- * - update in memory flags
82
- * - emit change event if needed
83
- *
84
- * @param resolve
85
- * @param flags
86
- * @param context
87
- * @param source For logging purposes
88
- * @private
89
- */
90
- private onIdentifyResolve;
83
+ private createPollingProcessor;
84
+ private createStreamingProcessor;
91
85
  off(eventName: EventName, listener: Function): void;
92
86
  on(eventName: EventName, listener: Function): void;
93
87
  track(key: string, data?: any, metricValue?: number): void;
@@ -103,5 +97,19 @@ export default class LDClientImpl implements LDClient {
103
97
  numberVariationDetail(key: string, defaultValue: number): LDEvaluationDetailTyped<number>;
104
98
  stringVariationDetail(key: string, defaultValue: string): LDEvaluationDetailTyped<string>;
105
99
  jsonVariationDetail(key: string, defaultValue: unknown): LDEvaluationDetailTyped<unknown>;
100
+ /**
101
+ * Inform the client of the network state. Can be used to modify connection behavior.
102
+ *
103
+ * For instance the implementation may choose to suppress errors from connections if the client
104
+ * knows that there is no network available.
105
+ * @param _available True when there is an available network.
106
+ */
107
+ protected setNetworkAvailability(available: boolean): void;
108
+ /**
109
+ * Enable/Disable event sending.
110
+ * @param enabled True to enable event processing, false to disable.
111
+ * @param flush True to flush while disabling. Useful to flush on certain state transitions.
112
+ */
113
+ protected setEventSendingEnabled(enabled: boolean, flush: boolean): void;
106
114
  }
107
115
  //# sourceMappingURL=LDClientImpl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LDClientImpl.d.ts","sourceRoot":"","sources":["../src/LDClientImpl.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LDClientImpl.d.ts","sourceRoot":"","sources":["../src/LDClientImpl.ts"],"names":[],"mappings":"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"}
@@ -3,10 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const js_sdk_common_1 = require("@launchdarkly/js-sdk-common");
4
4
  const LDEmitter_1 = require("./api/LDEmitter");
5
5
  const configuration_1 = require("./configuration");
6
+ const addAutoEnv_1 = require("./context/addAutoEnv");
7
+ const ensureKey_1 = require("./context/ensureKey");
6
8
  const createDiagnosticsManager_1 = require("./diagnostics/createDiagnosticsManager");
7
9
  const createEventProcessor_1 = require("./events/createEventProcessor");
8
10
  const EventFactory_1 = require("./events/EventFactory");
9
- const utils_1 = require("./utils");
11
+ const FlagManager_1 = require("./flag-manager/FlagManager");
12
+ const PollingProcessor_1 = require("./polling/PollingProcessor");
10
13
  const { createErrorEvaluationDetail, createSuccessEvaluationDetail, ClientMessages, ErrorKinds } = js_sdk_common_1.internal;
11
14
  class LDClientImpl {
12
15
  /**
@@ -20,7 +23,8 @@ class LDClientImpl {
20
23
  this.highTimeoutThreshold = 15;
21
24
  this.eventFactoryDefault = new EventFactory_1.default(false);
22
25
  this.eventFactoryWithReasons = new EventFactory_1.default(true);
23
- this.flags = {};
26
+ this.eventSendingEnabled = true;
27
+ this.networkAvailable = true;
24
28
  if (!sdkKey) {
25
29
  throw new Error('You must configure the client with a client-side SDK key');
26
30
  }
@@ -28,8 +32,10 @@ class LDClientImpl {
28
32
  throw new Error('Platform must implement Encoding because btoa is required.');
29
33
  }
30
34
  this.config = new configuration_1.default(options, internalOptions);
35
+ this.connectionMode = this.config.initialConnectionMode;
31
36
  this.clientContext = new js_sdk_common_1.ClientContext(sdkKey, this.config, platform);
32
37
  this.logger = this.config.logger;
38
+ this.flagManager = new FlagManager_1.default(this.platform, sdkKey, this.config.maxCachedContexts, this.config.logger);
33
39
  this.diagnosticsManager = (0, createDiagnosticsManager_1.default)(sdkKey, this.config, platform);
34
40
  this.eventProcessor = (0, createEventProcessor_1.default)(sdkKey, this.config, platform, this.diagnosticsManager, !this.isOffline());
35
41
  this.emitter = new LDEmitter_1.default();
@@ -39,6 +45,10 @@ class LDClientImpl {
39
45
  this.emitter.on('error', (c, err) => {
40
46
  this.logger.error(`error: ${err}, context: ${JSON.stringify(c)}`);
41
47
  });
48
+ this.flagManager.on((context, flagKeys) => {
49
+ const ldContext = js_sdk_common_1.Context.toLDContext(context);
50
+ this.emitter.emit('change', ldContext, flagKeys);
51
+ });
42
52
  }
43
53
  /**
44
54
  * Sets the SDK connection mode.
@@ -47,24 +57,25 @@ class LDClientImpl {
47
57
  */
48
58
  async setConnectionMode(mode) {
49
59
  var _a;
50
- if (this.config.connectionMode === mode) {
60
+ if (this.connectionMode === mode) {
51
61
  this.logger.debug(`setConnectionMode ignored. Mode is already '${mode}'.`);
52
62
  return Promise.resolve();
53
63
  }
54
- this.config.connectionMode = mode;
64
+ this.connectionMode = mode;
55
65
  this.logger.debug(`setConnectionMode ${mode}.`);
56
66
  switch (mode) {
57
67
  case 'offline':
58
- return this.close();
68
+ (_a = this.updateProcessor) === null || _a === void 0 ? void 0 : _a.close();
69
+ break;
70
+ case 'polling':
59
71
  case 'streaming':
60
- (_a = this.eventProcessor) === null || _a === void 0 ? void 0 : _a.start();
61
- if (this.context) {
62
- // identify will start streamer
63
- return this.identify(this.context, { timeout: this.identifyTimeout });
72
+ if (this.uncheckedContext) {
73
+ // identify will start the update processor
74
+ return this.identify(this.uncheckedContext, { timeout: this.identifyTimeout });
64
75
  }
65
76
  break;
66
77
  default:
67
- this.logger.warn(`Unknown ConnectionMode: ${mode}. Only 'offline' and 'streaming' are supported.`);
78
+ this.logger.warn(`Unknown ConnectionMode: ${mode}. Only 'offline', 'streaming', and 'polling' are supported.`);
68
79
  break;
69
80
  }
70
81
  return Promise.resolve();
@@ -73,104 +84,107 @@ class LDClientImpl {
73
84
  * Gets the SDK connection mode.
74
85
  */
75
86
  getConnectionMode() {
76
- return this.config.connectionMode;
87
+ return this.connectionMode;
77
88
  }
78
89
  isOffline() {
79
- return this.config.connectionMode === 'offline';
90
+ return this.connectionMode === 'offline';
80
91
  }
81
92
  allFlags() {
82
- const result = {};
83
- Object.entries(this.flags).forEach(([k, r]) => {
84
- if (!r.deleted) {
85
- result[k] = r.value;
93
+ // extracting all flag values
94
+ const result = Object.entries(this.flagManager.getAll()).reduce((acc, [key, descriptor]) => {
95
+ if (descriptor.flag !== null && descriptor.flag !== undefined && !descriptor.flag.deleted) {
96
+ acc[key] = descriptor.flag.value;
86
97
  }
87
- });
98
+ return acc;
99
+ }, {});
88
100
  return result;
89
101
  }
90
102
  async close() {
91
103
  var _a, _b;
92
104
  await this.flush();
93
105
  (_a = this.eventProcessor) === null || _a === void 0 ? void 0 : _a.close();
94
- (_b = this.streamer) === null || _b === void 0 ? void 0 : _b.close();
95
- this.logger.debug('Closed eventProcessor and streamer.');
106
+ (_b = this.updateProcessor) === null || _b === void 0 ? void 0 : _b.close();
107
+ this.logger.debug('Closed event processor and data source.');
96
108
  }
97
109
  async flush() {
98
110
  var _a;
99
111
  try {
100
112
  await ((_a = this.eventProcessor) === null || _a === void 0 ? void 0 : _a.flush());
101
- this.logger.debug('Successfully flushed eventProcessor.');
113
+ this.logger.debug('Successfully flushed event processor.');
102
114
  }
103
115
  catch (e) {
104
- this.logger.error(`Error flushing eventProcessor: ${e}.`);
116
+ this.logger.error(`Error flushing event processor: ${e}.`);
105
117
  return { error: e, result: false };
106
118
  }
107
119
  return { result: true };
108
120
  }
109
121
  getContext() {
110
- return this.context ? (0, js_sdk_common_1.clone)(this.context) : undefined;
122
+ // The LDContext returned here may have been modified by the SDK (for example: adding auto env attributes).
123
+ // We are returning an LDContext here to maintain a consistent represetnation of context to the consuming
124
+ // code. We are returned the unchecked context so that if a consumer identifies with an invalid context
125
+ // and then calls getContext, they get back the same context they provided, without any assertion about
126
+ // validity.
127
+ return this.uncheckedContext ? (0, js_sdk_common_1.clone)(this.uncheckedContext) : undefined;
111
128
  }
112
- createStreamListeners(context, canonicalKey, identifyResolve) {
129
+ createStreamListeners(context, identifyResolve) {
113
130
  const listeners = new Map();
114
131
  listeners.set('put', {
115
132
  deserializeData: JSON.parse,
116
- processJson: async (dataJson) => {
117
- var _a;
118
- this.logger.debug(`Streamer PUT: ${Object.keys(dataJson)}`);
119
- this.onIdentifyResolve(identifyResolve, dataJson, context, 'streamer PUT');
120
- await ((_a = this.platform.storage) === null || _a === void 0 ? void 0 : _a.set(canonicalKey, JSON.stringify(this.flags)));
133
+ processJson: async (evalResults) => {
134
+ this.logger.debug(`Stream PUT: ${Object.keys(evalResults)}`);
135
+ // mapping flags to item descriptors
136
+ const descriptors = Object.entries(evalResults).reduce((acc, [key, flag]) => {
137
+ acc[key] = { version: flag.version, flag };
138
+ return acc;
139
+ }, {});
140
+ await this.flagManager.init(context, descriptors).then(identifyResolve());
121
141
  },
122
142
  });
123
143
  listeners.set('patch', {
124
144
  deserializeData: JSON.parse,
125
- processJson: async (dataJson) => {
126
- var _a;
127
- this.logger.debug(`Streamer PATCH ${JSON.stringify(dataJson, null, 2)}`);
128
- const existing = this.flags[dataJson.key];
129
- // add flag if it doesn't exist or update it if version is newer
130
- if (!existing || (existing && dataJson.version > existing.version)) {
131
- this.flags[dataJson.key] = dataJson;
132
- await ((_a = this.platform.storage) === null || _a === void 0 ? void 0 : _a.set(canonicalKey, JSON.stringify(this.flags)));
133
- const changedKeys = [dataJson.key];
134
- this.logger.debug(`Emitting changes from PATCH: ${changedKeys}`);
135
- this.emitter.emit('change', context, changedKeys);
136
- }
145
+ processJson: async (patchFlag) => {
146
+ this.logger.debug(`Stream PATCH ${JSON.stringify(patchFlag, null, 2)}`);
147
+ this.flagManager.upsert(context, patchFlag.key, {
148
+ version: patchFlag.version,
149
+ flag: patchFlag,
150
+ });
137
151
  },
138
152
  });
139
153
  listeners.set('delete', {
140
154
  deserializeData: JSON.parse,
141
- processJson: async (dataJson) => {
142
- var _a;
143
- this.logger.debug(`Streamer DELETE ${JSON.stringify(dataJson, null, 2)}`);
144
- const existing = this.flags[dataJson.key];
145
- // the deleted flag is saved as tombstoned
146
- if (!existing || existing.version < dataJson.version) {
147
- this.flags[dataJson.key] = Object.assign(Object.assign({}, dataJson), { deleted: true,
155
+ processJson: async (deleteFlag) => {
156
+ this.logger.debug(`Stream DELETE ${JSON.stringify(deleteFlag, null, 2)}`);
157
+ this.flagManager.upsert(context, deleteFlag.key, {
158
+ version: deleteFlag.version,
159
+ flag: Object.assign(Object.assign({}, deleteFlag), { deleted: true,
148
160
  // props below are set to sensible defaults. they are irrelevant
149
161
  // because this flag has been deleted.
150
- flagVersion: 0, value: undefined, variation: 0, trackEvents: false });
151
- await ((_a = this.platform.storage) === null || _a === void 0 ? void 0 : _a.set(canonicalKey, JSON.stringify(this.flags)));
152
- const changedKeys = [dataJson.key];
153
- this.logger.debug(`Emitting changes from DELETE: ${changedKeys}`);
154
- this.emitter.emit('change', context, changedKeys);
155
- }
162
+ flagVersion: 0, value: undefined, variation: 0, trackEvents: false }),
163
+ });
156
164
  },
157
165
  });
158
166
  return listeners;
159
167
  }
160
168
  /**
161
- * Generates the url path for streamer.
162
- *
163
- * For mobile key: /meval/${base64-encoded-context}
164
- * For clientSideId: /eval/${envId}/${base64-encoded-context}
169
+ * Generates the url path for streaming.
165
170
  *
166
- * the path.
167
- *
168
- * @protected This function must be overridden in subclasses for streamer
171
+ * @protected This function must be overridden in subclasses for streaming
169
172
  * to work.
170
173
  * @param _context The LDContext object
171
174
  */
172
175
  createStreamUriPath(_context) {
173
- throw new Error('createStreamUriPath not implemented. Client sdks must implement createStreamUriPath for streamer to work.');
176
+ throw new Error('createStreamUriPath not implemented. Client sdks must implement createStreamUriPath for streaming to work.');
177
+ }
178
+ /**
179
+ * Generates the url path for polling.
180
+ * @param _context
181
+ *
182
+ * @protected This function must be overridden in subclasses for polling
183
+ * to work.
184
+ * @param _context The LDContext object
185
+ */
186
+ createPollUriPath(_context) {
187
+ throw new Error('createPollUriPath not implemented. Client sdks must implement createPollUriPath for polling to work.');
174
188
  }
175
189
  createIdentifyPromise(timeout) {
176
190
  let res;
@@ -188,11 +202,6 @@ class LDClientImpl {
188
202
  });
189
203
  return { identifyPromise: raced, identifyResolve: res, identifyReject: rej };
190
204
  }
191
- async getFlagsFromStorage(canonicalKey) {
192
- var _a;
193
- const f = await ((_a = this.platform.storage) === null || _a === void 0 ? void 0 : _a.get(canonicalKey));
194
- return f ? JSON.parse(f) : undefined;
195
- }
196
205
  /**
197
206
  * Identifies a context to LaunchDarkly. See {@link LDClient.identify}.
198
207
  *
@@ -214,13 +223,13 @@ class LDClientImpl {
214
223
  this.identifyTimeout = identifyOptions.timeout;
215
224
  }
216
225
  if (this.identifyTimeout > this.highTimeoutThreshold) {
217
- this.logger.warn('The identify function was called with a timeout greater than' +
218
- `${this.highTimeoutThreshold} seconds. We recommend a timeout of less than` +
226
+ this.logger.warn('The identify function was called with a timeout greater than ' +
227
+ `${this.highTimeoutThreshold} seconds. We recommend a timeout of less than ` +
219
228
  `${this.highTimeoutThreshold} seconds.`);
220
229
  }
221
- let context = await (0, utils_1.ensureKey)(pristineContext, this.platform);
230
+ let context = await (0, ensureKey_1.ensureKey)(pristineContext, this.platform);
222
231
  if (this.autoEnvAttributes === js_sdk_common_1.AutoEnvAttributes.Enabled) {
223
- context = await (0, utils_1.addAutoEnv)(context, this.platform, this.config);
232
+ context = await (0, addAutoEnv_1.addAutoEnv)(context, this.platform, this.config);
224
233
  }
225
234
  const checkedContext = js_sdk_common_1.Context.fromLDContext(context);
226
235
  if (!checkedContext.valid) {
@@ -228,64 +237,67 @@ class LDClientImpl {
228
237
  this.emitter.emit('error', context, error);
229
238
  return Promise.reject(error);
230
239
  }
231
- (_a = this.eventProcessor) === null || _a === void 0 ? void 0 : _a.sendEvent(this.eventFactoryDefault.identifyEvent(checkedContext));
240
+ this.uncheckedContext = context;
241
+ this.checkedContext = checkedContext;
242
+ (_a = this.eventProcessor) === null || _a === void 0 ? void 0 : _a.sendEvent(this.eventFactoryDefault.identifyEvent(this.checkedContext));
232
243
  const { identifyPromise, identifyResolve, identifyReject } = this.createIdentifyPromise(this.identifyTimeout);
233
- this.logger.debug(`Identifying ${JSON.stringify(context)}`);
234
- const flagsStorage = await this.getFlagsFromStorage(checkedContext.canonicalKey);
235
- if (flagsStorage) {
236
- this.logger.debug('Using storage');
237
- this.onIdentifyResolve(identifyResolve, flagsStorage, context, 'identify storage');
244
+ this.logger.debug(`Identifying ${JSON.stringify(this.checkedContext)}`);
245
+ const loadedFromCache = await this.flagManager.loadCached(this.checkedContext);
246
+ if (loadedFromCache) {
247
+ identifyResolve();
238
248
  }
239
249
  if (this.isOffline()) {
240
- if (flagsStorage) {
250
+ if (loadedFromCache) {
241
251
  this.logger.debug('Offline identify using storage flags.');
242
252
  }
243
253
  else {
244
254
  this.logger.debug('Offline identify no storage. Defaults will be used.');
245
- this.context = context;
246
- this.flags = {};
247
255
  identifyResolve();
248
256
  }
249
257
  }
250
258
  else {
251
- (_b = this.streamer) === null || _b === void 0 ? void 0 : _b.close();
252
- let streamUri = this.createStreamUriPath(context);
253
- if (this.config.withReasons) {
254
- streamUri = `${streamUri}?withReasons=true`;
259
+ (_b = this.updateProcessor) === null || _b === void 0 ? void 0 : _b.close();
260
+ switch (this.getConnectionMode()) {
261
+ case 'streaming':
262
+ this.createStreamingProcessor(context, checkedContext, identifyResolve, identifyReject);
263
+ break;
264
+ case 'polling':
265
+ this.createPollingProcessor(context, checkedContext, identifyResolve, identifyReject);
266
+ break;
267
+ default:
268
+ break;
255
269
  }
256
- this.streamer = new js_sdk_common_1.internal.StreamingProcessor(this.sdkKey, this.clientContext, streamUri, this.createStreamListeners(context, checkedContext.canonicalKey, identifyResolve), this.diagnosticsManager, (e) => {
257
- identifyReject(e);
258
- this.emitter.emit('error', context, e);
259
- });
260
- this.streamer.start();
270
+ this.updateProcessor.start();
261
271
  }
262
272
  return identifyPromise;
263
273
  }
264
- /**
265
- * Performs common tasks when resolving the identify promise:
266
- * - resolve the promise
267
- * - update in memory context
268
- * - update in memory flags
269
- * - emit change event if needed
270
- *
271
- * @param resolve
272
- * @param flags
273
- * @param context
274
- * @param source For logging purposes
275
- * @private
276
- */
277
- onIdentifyResolve(resolve, flags, context, source) {
278
- resolve();
279
- const changedKeys = (0, utils_1.calculateFlagChanges)(this.flags, flags);
280
- this.context = context;
281
- this.flags = flags;
282
- if (changedKeys.length > 0) {
283
- this.emitter.emit('change', context, changedKeys);
284
- this.logger.debug(`OnIdentifyResolve emitting changes from: ${source}.`);
274
+ createPollingProcessor(context, checkedContext, identifyResolve, identifyReject) {
275
+ let pollingPath = this.createPollUriPath(context);
276
+ if (this.config.withReasons) {
277
+ pollingPath = `${pollingPath}?withReasons=true`;
285
278
  }
286
- else {
287
- this.logger.debug(`OnIdentifyResolve no changes to emit from: ${source}.`);
279
+ this.updateProcessor = new PollingProcessor_1.default(this.sdkKey, this.clientContext.platform.requests, this.clientContext.platform.info, pollingPath, this.config, async (flags) => {
280
+ this.logger.debug(`Handling polling result: ${Object.keys(flags)}`);
281
+ // mapping flags to item descriptors
282
+ const descriptors = Object.entries(flags).reduce((acc, [key, flag]) => {
283
+ acc[key] = { version: flag.version, flag };
284
+ return acc;
285
+ }, {});
286
+ await this.flagManager.init(checkedContext, descriptors).then(identifyResolve());
287
+ }, (err) => {
288
+ identifyReject(err);
289
+ this.emitter.emit('error', context, err);
290
+ });
291
+ }
292
+ createStreamingProcessor(context, checkedContext, identifyResolve, identifyReject) {
293
+ let streamingPath = this.createStreamUriPath(context);
294
+ if (this.config.withReasons) {
295
+ streamingPath = `${streamingPath}?withReasons=true`;
288
296
  }
297
+ this.updateProcessor = new js_sdk_common_1.internal.StreamingProcessor(this.sdkKey, this.clientContext, streamingPath, this.createStreamListeners(checkedContext, identifyResolve), this.diagnosticsManager, (e) => {
298
+ identifyReject(e);
299
+ this.emitter.emit('error', context, e);
300
+ });
289
301
  }
290
302
  off(eventName, listener) {
291
303
  this.emitter.off(eventName, listener);
@@ -295,12 +307,7 @@ class LDClientImpl {
295
307
  }
296
308
  track(key, data, metricValue) {
297
309
  var _a, _b;
298
- if (!this.context) {
299
- this.logger.warn(ClientMessages.missingContextKeyNoEvent);
300
- return;
301
- }
302
- const checkedContext = js_sdk_common_1.Context.fromLDContext(this.context);
303
- if (!checkedContext.valid) {
310
+ if (!this.checkedContext || !this.checkedContext.valid) {
304
311
  this.logger.warn(ClientMessages.missingContextKeyNoEvent);
305
312
  return;
306
313
  }
@@ -308,31 +315,31 @@ class LDClientImpl {
308
315
  if (metricValue !== undefined && !js_sdk_common_1.TypeValidators.Number.is(metricValue)) {
309
316
  (_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn(ClientMessages.invalidMetricValue(typeof metricValue));
310
317
  }
311
- (_b = this.eventProcessor) === null || _b === void 0 ? void 0 : _b.sendEvent(this.eventFactoryDefault.customEvent(key, checkedContext, data, metricValue));
318
+ (_b = this.eventProcessor) === null || _b === void 0 ? void 0 : _b.sendEvent(this.eventFactoryDefault.customEvent(key, this.checkedContext, data, metricValue));
312
319
  }
313
320
  variationInternal(flagKey, defaultValue, eventFactory, typeChecker) {
314
321
  var _a, _b, _c;
315
- if (!this.context) {
322
+ if (!this.uncheckedContext) {
316
323
  this.logger.debug(ClientMessages.missingContextKeyNoEvent);
317
324
  return createErrorEvaluationDetail(ErrorKinds.UserNotSpecified, defaultValue);
318
325
  }
319
- const evalContext = js_sdk_common_1.Context.fromLDContext(this.context);
320
- const found = this.flags[flagKey];
321
- if (!found || found.deleted) {
326
+ const evalContext = js_sdk_common_1.Context.fromLDContext(this.uncheckedContext);
327
+ const foundItem = this.flagManager.get(flagKey);
328
+ if (foundItem === undefined || foundItem.flag.deleted) {
322
329
  const defVal = defaultValue !== null && defaultValue !== void 0 ? defaultValue : null;
323
330
  const error = new js_sdk_common_1.LDClientError(`Unknown feature flag "${flagKey}"; returning default value ${defVal}.`);
324
- this.emitter.emit('error', this.context, error);
331
+ this.emitter.emit('error', this.uncheckedContext, error);
325
332
  (_a = this.eventProcessor) === null || _a === void 0 ? void 0 : _a.sendEvent(this.eventFactoryDefault.unknownFlagEvent(flagKey, defVal, evalContext));
326
333
  return createErrorEvaluationDetail(ErrorKinds.FlagNotFound, defaultValue);
327
334
  }
328
- const { reason, value, variation } = found;
335
+ const { reason, value, variation } = foundItem.flag;
329
336
  if (typeChecker) {
330
337
  const [matched, type] = typeChecker(value);
331
338
  if (!matched) {
332
339
  (_b = this.eventProcessor) === null || _b === void 0 ? void 0 : _b.sendEvent(eventFactory.evalEventClient(flagKey, defaultValue, // track default value on type errors
333
- defaultValue, found, evalContext, reason));
340
+ defaultValue, foundItem.flag, evalContext, reason));
334
341
  const error = new js_sdk_common_1.LDClientError(`Wrong type "${type}" for feature flag "${flagKey}"; returning default value`);
335
- this.emitter.emit('error', this.context, error);
342
+ this.emitter.emit('error', this.uncheckedContext, error);
336
343
  return createErrorEvaluationDetail(ErrorKinds.WrongType, defaultValue);
337
344
  }
338
345
  }
@@ -341,7 +348,7 @@ class LDClientImpl {
341
348
  this.logger.debug('Result value is null in variation');
342
349
  successDetail.value = defaultValue;
343
350
  }
344
- (_c = this.eventProcessor) === null || _c === void 0 ? void 0 : _c.sendEvent(eventFactory.evalEventClient(flagKey, value, defaultValue, found, evalContext, reason));
351
+ (_c = this.eventProcessor) === null || _c === void 0 ? void 0 : _c.sendEvent(eventFactory.evalEventClient(flagKey, value, defaultValue, foundItem.flag, evalContext, reason));
345
352
  return successDetail;
346
353
  }
347
354
  variation(flagKey, defaultValue) {
@@ -396,6 +403,51 @@ class LDClientImpl {
396
403
  jsonVariationDetail(key, defaultValue) {
397
404
  return this.variationDetail(key, defaultValue);
398
405
  }
406
+ /**
407
+ * Inform the client of the network state. Can be used to modify connection behavior.
408
+ *
409
+ * For instance the implementation may choose to suppress errors from connections if the client
410
+ * knows that there is no network available.
411
+ * @param _available True when there is an available network.
412
+ */
413
+ setNetworkAvailability(available) {
414
+ this.networkAvailable = available;
415
+ // Not yet supported.
416
+ }
417
+ /**
418
+ * Enable/Disable event sending.
419
+ * @param enabled True to enable event processing, false to disable.
420
+ * @param flush True to flush while disabling. Useful to flush on certain state transitions.
421
+ */
422
+ setEventSendingEnabled(enabled, flush) {
423
+ var _a, _b, _c, _d;
424
+ if (this.eventSendingEnabled === enabled) {
425
+ return;
426
+ }
427
+ this.eventSendingEnabled = enabled;
428
+ if (enabled) {
429
+ this.logger.debug('Starting event processor');
430
+ (_a = this.eventProcessor) === null || _a === void 0 ? void 0 : _a.start();
431
+ }
432
+ else if (flush) {
433
+ (_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug('Flushing event processor before disabling.');
434
+ // Disable and flush.
435
+ this.flush().then(() => {
436
+ var _a, _b;
437
+ // While waiting for the flush event sending could be re-enabled, in which case
438
+ // we do not want to close the event processor.
439
+ if (!this.eventSendingEnabled) {
440
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug('Stopping event processor.');
441
+ (_b = this.eventProcessor) === null || _b === void 0 ? void 0 : _b.close();
442
+ }
443
+ });
444
+ }
445
+ else {
446
+ // Just disabled.
447
+ (_c = this.logger) === null || _c === void 0 ? void 0 : _c.debug('Stopping event processor.');
448
+ (_d = this.eventProcessor) === null || _d === void 0 ? void 0 : _d.close();
449
+ }
450
+ }
399
451
  }
400
452
  exports.default = LDClientImpl;
401
453
  //# sourceMappingURL=LDClientImpl.js.map