@flopflip/launchdarkly-adapter 14.0.2 → 15.0.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.
package/dist/index.cjs ADDED
@@ -0,0 +1,431 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __typeError = (msg) => {
8
+ throw TypeError(msg);
9
+ };
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __spreadValues = (a, b) => {
12
+ for (var prop in b || (b = {}))
13
+ if (__hasOwnProp.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ if (__getOwnPropSymbols)
16
+ for (var prop of __getOwnPropSymbols(b)) {
17
+ if (__propIsEnum.call(b, prop))
18
+ __defNormalProp(a, prop, b[prop]);
19
+ }
20
+ return a;
21
+ };
22
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
23
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
24
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
25
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
26
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
27
+ var __async = (__this, __arguments, generator) => {
28
+ return new Promise((resolve, reject) => {
29
+ var fulfilled = (value) => {
30
+ try {
31
+ step(generator.next(value));
32
+ } catch (e) {
33
+ reject(e);
34
+ }
35
+ };
36
+ var rejected = (value) => {
37
+ try {
38
+ step(generator.throw(value));
39
+ } catch (e) {
40
+ reject(e);
41
+ }
42
+ };
43
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
44
+ step((generator = generator.apply(__this, __arguments)).next());
45
+ });
46
+ };
47
+
48
+ // src/adapter.ts
49
+
50
+
51
+
52
+
53
+
54
+ var _adapterutilities = require('@flopflip/adapter-utilities');
55
+ var _cache = require('@flopflip/cache');
56
+
57
+
58
+
59
+
60
+
61
+
62
+ var _types = require('@flopflip/types');
63
+ var _debouncefn = require('debounce-fn'); var _debouncefn2 = _interopRequireDefault(_debouncefn);
64
+
65
+
66
+ var _launchdarklyjsclientsdk = require('launchdarkly-js-client-sdk');
67
+ var _isEqual = require('lodash/isEqual'); var _isEqual2 = _interopRequireDefault(_isEqual);
68
+ var _mitt = require('mitt'); var _mitt2 = _interopRequireDefault(_mitt);
69
+ var _tinywarning = require('tiny-warning'); var _tinywarning2 = _interopRequireDefault(_tinywarning);
70
+ var _tsdeepmerge = require('ts-deepmerge');
71
+ var _adapterState, _updateFlagsInAdapterState, _getIsAdapterUnsubscribed, _getIsFlagUnsubcribed, _getIsFlagLocked, _withoutUnsubscribedOrLockedFlags, _getIsAnonymousContext, _ensureContext, _initializeClient, _changeClientContext, _maybeUpdateFlagsInCache, _getInitialFlags, _didFlagChange, _setupFlagSubcription;
72
+ var LaunchDarklyAdapter = class {
73
+ constructor() {
74
+ __privateAdd(this, _adapterState);
75
+ __privateAdd(this, _updateFlagsInAdapterState, (flags, options) => {
76
+ const updatedFlags = Object.entries(flags).reduce(
77
+ (updatedFlags2, [flagName, flagValue]) => {
78
+ if (__privateGet(this, _getIsFlagLocked).call(this, flagName)) {
79
+ return updatedFlags2;
80
+ }
81
+ if (options == null ? void 0 : options.lockFlags) {
82
+ __privateGet(this, _adapterState).lockedFlags.add(flagName);
83
+ }
84
+ if (options == null ? void 0 : options.unsubscribeFlags) {
85
+ __privateGet(this, _adapterState).unsubscribedFlags.add(flagName);
86
+ }
87
+ const updated = __spreadProps(__spreadValues({}, updatedFlags2), {
88
+ [flagName]: flagValue
89
+ });
90
+ return updated;
91
+ },
92
+ {}
93
+ );
94
+ __privateGet(this, _adapterState).flags = __spreadValues(__spreadValues({}, __privateGet(this, _adapterState).flags), updatedFlags);
95
+ });
96
+ __privateAdd(this, _getIsAdapterUnsubscribed, () => __privateGet(this, _adapterState).subscriptionStatus === _types.AdapterSubscriptionStatus.Unsubscribed);
97
+ __privateAdd(this, _getIsFlagUnsubcribed, (flagName) => __privateGet(this, _adapterState).unsubscribedFlags.has(flagName));
98
+ __privateAdd(this, _getIsFlagLocked, (flagName) => __privateGet(this, _adapterState).lockedFlags.has(flagName));
99
+ __privateAdd(this, _withoutUnsubscribedOrLockedFlags, (flags) => Object.fromEntries(
100
+ Object.entries(flags).filter(
101
+ ([flagName]) => !__privateGet(this, _getIsFlagUnsubcribed).call(this, flagName) && !__privateGet(this, _getIsFlagLocked).call(this, flagName)
102
+ )
103
+ ));
104
+ __privateAdd(this, _getIsAnonymousContext, (context) => !(context == null ? void 0 : context.key));
105
+ __privateAdd(this, _ensureContext, (context) => {
106
+ const isAnonymousContext = __privateGet(this, _getIsAnonymousContext).call(this, context);
107
+ return _tsdeepmerge.merge.call(void 0, context, {
108
+ key: isAnonymousContext ? void 0 : context.key,
109
+ anonymous: isAnonymousContext
110
+ });
111
+ });
112
+ __privateAdd(this, _initializeClient, (clientSideId, context, options) => _launchdarklyjsclientsdk.initialize.call(void 0, clientSideId, context, options));
113
+ __privateAdd(this, _changeClientContext, (nextContext) => __async(this, null, function* () {
114
+ var _a;
115
+ return ((_a = __privateGet(this, _adapterState).client) == null ? void 0 : _a.identify) ? __privateGet(this, _adapterState).client.identify(nextContext) : Promise.reject(
116
+ new Error("Can not change user context: client not yet initialized.")
117
+ );
118
+ }));
119
+ __privateAdd(this, _maybeUpdateFlagsInCache, (flagsToCache, cacheIdentifier) => __async(this, null, function* () {
120
+ if (cacheIdentifier) {
121
+ const cache = yield _cache.getCache.call(void 0,
122
+ cacheIdentifier,
123
+ _types.adapterIdentifiers.launchdarkly,
124
+ // NOTE: LDContextCommon is part of the type which we never use.
125
+ __privateGet(this, _adapterState).context
126
+ );
127
+ const cachedFlags = cache.get();
128
+ cache.set(__spreadValues(__spreadValues({}, cachedFlags), flagsToCache));
129
+ }
130
+ }));
131
+ __privateAdd(this, _getInitialFlags, (_0) => __async(this, [_0], function* ({
132
+ flags,
133
+ throwOnInitializationFailure,
134
+ cacheIdentifier,
135
+ cacheMode,
136
+ initializationTimeout
137
+ }) {
138
+ if (__privateGet(this, _adapterState).client) {
139
+ return __privateGet(this, _adapterState).client.waitForInitialization(initializationTimeout).then(() => __async(this, null, function* () {
140
+ let flagsFromSdk;
141
+ if (__privateGet(this, _adapterState).client && !flags) {
142
+ flagsFromSdk = __privateGet(this, _adapterState).client.allFlags();
143
+ } else if (__privateGet(this, _adapterState).client && flags) {
144
+ flagsFromSdk = {};
145
+ for (const [requestedFlagName, defaultFlagValue] of Object.entries(
146
+ flags
147
+ )) {
148
+ const denormalizedRequestedFlagName = _adapterutilities.denormalizeFlagName.call(void 0, requestedFlagName);
149
+ flagsFromSdk[denormalizedRequestedFlagName] = __privateGet(this, _adapterState).client.variation(
150
+ denormalizedRequestedFlagName,
151
+ defaultFlagValue
152
+ );
153
+ }
154
+ }
155
+ if (flagsFromSdk) {
156
+ const normalizedFlags = _adapterutilities.normalizeFlags.call(void 0, flagsFromSdk);
157
+ yield __privateGet(this, _maybeUpdateFlagsInCache).call(this, normalizedFlags, cacheIdentifier);
158
+ const flags2 = __privateGet(this, _withoutUnsubscribedOrLockedFlags).call(this, normalizedFlags);
159
+ __privateGet(this, _updateFlagsInAdapterState).call(this, flags2);
160
+ if (cacheMode !== _types.cacheModes.lazy) {
161
+ __privateGet(this, _adapterState).emitter.emit(
162
+ "flagsStateChange",
163
+ __privateGet(this, _adapterState).flags
164
+ );
165
+ }
166
+ }
167
+ this.setConfigurationStatus(_types.AdapterConfigurationStatus.Configured);
168
+ return Promise.resolve({
169
+ flagsFromSdk,
170
+ initializationStatus: _types.AdapterInitializationStatus.Succeeded
171
+ });
172
+ })).catch(() => __async(this, null, function* () {
173
+ if (throwOnInitializationFailure) {
174
+ return Promise.reject(
175
+ new Error(
176
+ "@flopflip/launchdarkly-adapter: adapter failed to initialize."
177
+ )
178
+ );
179
+ }
180
+ console.warn(
181
+ "@flopflip/launchdarkly-adapter: adapter failed to initialize."
182
+ );
183
+ return Promise.resolve({
184
+ flagsFromSdk: void 0,
185
+ initializationStatus: _types.AdapterInitializationStatus.Failed
186
+ });
187
+ }));
188
+ }
189
+ return Promise.reject(
190
+ new Error(
191
+ "@flopflip/launchdarkly-adapter: can not subscribe with non initialized client."
192
+ )
193
+ );
194
+ }));
195
+ __privateAdd(this, _didFlagChange, (flagName, nextFlagValue) => {
196
+ const previousFlagValue = this.getFlag(flagName);
197
+ if (previousFlagValue === void 0) {
198
+ return true;
199
+ }
200
+ return previousFlagValue !== nextFlagValue;
201
+ });
202
+ __privateAdd(this, _setupFlagSubcription, ({
203
+ flagsFromSdk,
204
+ flagsUpdateDelayMs,
205
+ cacheIdentifier,
206
+ cacheMode
207
+ }) => {
208
+ for (const flagName in flagsFromSdk) {
209
+ if (Object.hasOwn(flagsFromSdk, flagName) && __privateGet(this, _adapterState).client) {
210
+ __privateGet(this, _adapterState).client.on(
211
+ `change:${flagName}`,
212
+ (flagValue) => __async(this, null, function* () {
213
+ const [normalizedFlagName, normalizedFlagValue] = _adapterutilities.normalizeFlag.call(void 0,
214
+ flagName,
215
+ flagValue
216
+ );
217
+ yield __privateGet(this, _maybeUpdateFlagsInCache).call(this, {
218
+ [normalizedFlagName]: normalizedFlagValue
219
+ }, cacheIdentifier);
220
+ if (__privateGet(this, _getIsFlagUnsubcribed).call(this, normalizedFlagName)) {
221
+ return;
222
+ }
223
+ if (!__privateGet(this, _didFlagChange).call(this, normalizedFlagName, normalizedFlagValue)) {
224
+ return;
225
+ }
226
+ const updatedFlags = {
227
+ [normalizedFlagName]: normalizedFlagValue
228
+ };
229
+ __privateGet(this, _updateFlagsInAdapterState).call(this, updatedFlags);
230
+ const flushFlagsUpdate = () => {
231
+ if (cacheMode === _types.cacheModes.lazy) {
232
+ return;
233
+ }
234
+ __privateGet(this, _adapterState).emitter.emit(
235
+ "flagsStateChange",
236
+ __privateGet(this, _adapterState).flags
237
+ );
238
+ };
239
+ const scheduleImmediately = { before: true, after: false };
240
+ const scheduleTrailingEdge = { before: false, after: true };
241
+ _debouncefn2.default.call(void 0, flushFlagsUpdate, __spreadValues({
242
+ wait: flagsUpdateDelayMs
243
+ }, flagsUpdateDelayMs ? scheduleTrailingEdge : scheduleImmediately))();
244
+ })
245
+ );
246
+ }
247
+ }
248
+ });
249
+ // External. Flags are autolocked when updated.
250
+ this.updateFlags = (flags, options) => {
251
+ __privateGet(this, _updateFlagsInAdapterState).call(this, flags, options);
252
+ __privateGet(this, _adapterState).emitter.emit(
253
+ "flagsStateChange",
254
+ __privateGet(this, _adapterState).flags
255
+ );
256
+ };
257
+ this.unsubscribe = () => {
258
+ __privateGet(this, _adapterState).subscriptionStatus = _types.AdapterSubscriptionStatus.Unsubscribed;
259
+ };
260
+ this.subscribe = () => {
261
+ __privateGet(this, _adapterState).subscriptionStatus = _types.AdapterSubscriptionStatus.Subscribed;
262
+ };
263
+ __privateSet(this, _adapterState, {
264
+ subscriptionStatus: _types.AdapterSubscriptionStatus.Subscribed,
265
+ configurationStatus: _types.AdapterConfigurationStatus.Unconfigured,
266
+ context: void 0,
267
+ client: void 0,
268
+ flags: {},
269
+ // Typings are incorrect and state that mitt is not callable.
270
+ // Value of type 'MittStatic' is not callable. Did you mean to include 'new'
271
+ emitter: _mitt2.default.call(void 0, ),
272
+ lockedFlags: /* @__PURE__ */ new Set(),
273
+ unsubscribedFlags: /* @__PURE__ */ new Set()
274
+ });
275
+ this.id = _types.adapterIdentifiers.launchdarkly;
276
+ }
277
+ configure(adapterArgs, adapterEventHandlers) {
278
+ return __async(this, null, function* () {
279
+ var _a;
280
+ const handleFlagsChange = (nextFlags) => {
281
+ if (__privateGet(this, _getIsAdapterUnsubscribed).call(this)) {
282
+ return;
283
+ }
284
+ adapterEventHandlers.onFlagsStateChange({
285
+ flags: nextFlags,
286
+ id: this.id
287
+ });
288
+ };
289
+ const handleStatusChange = (nextStatus) => {
290
+ if (__privateGet(this, _getIsAdapterUnsubscribed).call(this)) {
291
+ return;
292
+ }
293
+ adapterEventHandlers.onStatusStateChange({
294
+ status: nextStatus,
295
+ id: this.id
296
+ });
297
+ };
298
+ __privateGet(this, _adapterState).configurationStatus = _types.AdapterConfigurationStatus.Configuring;
299
+ __privateGet(this, _adapterState).emitter.on("flagsStateChange", handleFlagsChange);
300
+ __privateGet(this, _adapterState).emitter.on("statusStateChange", handleStatusChange);
301
+ __privateGet(this, _adapterState).emitter.emit("statusStateChange", {
302
+ configurationStatus: __privateGet(this, _adapterState).configurationStatus
303
+ });
304
+ const {
305
+ sdk,
306
+ context,
307
+ flags,
308
+ throwOnInitializationFailure = false,
309
+ initializationTimeout = 2,
310
+ // 2 seconds
311
+ flagsUpdateDelayMs
312
+ } = adapterArgs;
313
+ let cachedFlags;
314
+ __privateGet(this, _adapterState).context = __privateGet(this, _ensureContext).call(this, context);
315
+ if (adapterArgs.cacheIdentifier) {
316
+ const cache = yield _cache.getCache.call(void 0,
317
+ adapterArgs.cacheIdentifier,
318
+ _types.adapterIdentifiers.launchdarkly,
319
+ __privateGet(this, _adapterState).context
320
+ );
321
+ cachedFlags = cache.get();
322
+ if (cachedFlags) {
323
+ __privateGet(this, _updateFlagsInAdapterState).call(this, cachedFlags);
324
+ __privateGet(this, _adapterState).flags = cachedFlags;
325
+ __privateGet(this, _adapterState).emitter.emit("flagsStateChange", cachedFlags);
326
+ }
327
+ }
328
+ __privateGet(this, _adapterState).client = __privateGet(this, _initializeClient).call(this, sdk.clientSideId, __privateGet(this, _adapterState).context, (_a = sdk.clientOptions) != null ? _a : {});
329
+ return __privateGet(this, _getInitialFlags).call(this, {
330
+ flags,
331
+ throwOnInitializationFailure,
332
+ cacheIdentifier: adapterArgs.cacheIdentifier,
333
+ cacheMode: adapterArgs.cacheMode,
334
+ initializationTimeout
335
+ }).then(({ flagsFromSdk, initializationStatus }) => {
336
+ if (flagsFromSdk) {
337
+ __privateGet(this, _setupFlagSubcription).call(this, {
338
+ flagsFromSdk,
339
+ flagsUpdateDelayMs,
340
+ cacheIdentifier: adapterArgs.cacheIdentifier,
341
+ cacheMode: adapterArgs.cacheMode
342
+ });
343
+ }
344
+ return { initializationStatus };
345
+ });
346
+ });
347
+ }
348
+ reconfigure(adapterArgs, _adapterEventHandlers) {
349
+ return __async(this, null, function* () {
350
+ if (!this.getIsConfigurationStatus(_types.AdapterConfigurationStatus.Configured)) {
351
+ return Promise.reject(
352
+ new Error(
353
+ "@flopflip/launchdarkly-adapter: please configure adapter before reconfiguring."
354
+ )
355
+ );
356
+ }
357
+ const nextContext = __privateGet(this, _ensureContext).call(this, adapterArgs.context);
358
+ if (!_isEqual2.default.call(void 0, __privateGet(this, _adapterState).context, nextContext)) {
359
+ if (adapterArgs.cacheIdentifier) {
360
+ const cache = yield _cache.getCache.call(void 0,
361
+ adapterArgs.cacheIdentifier,
362
+ _types.adapterIdentifiers.launchdarkly,
363
+ __privateGet(this, _adapterState).context
364
+ );
365
+ cache.unset();
366
+ }
367
+ __privateGet(this, _adapterState).context = nextContext;
368
+ yield __privateGet(this, _changeClientContext).call(this, __privateGet(this, _adapterState).context);
369
+ }
370
+ return Promise.resolve({
371
+ initializationStatus: _types.AdapterInitializationStatus.Succeeded
372
+ });
373
+ });
374
+ }
375
+ getIsConfigurationStatus(configurationStatus) {
376
+ return __privateGet(this, _adapterState).configurationStatus === configurationStatus;
377
+ }
378
+ setConfigurationStatus(nextConfigurationStatus) {
379
+ __privateGet(this, _adapterState).configurationStatus = nextConfigurationStatus;
380
+ __privateGet(this, _adapterState).emitter.emit("statusStateChange", {
381
+ configurationStatus: __privateGet(this, _adapterState).configurationStatus
382
+ });
383
+ }
384
+ getClient() {
385
+ return __privateGet(this, _adapterState).client;
386
+ }
387
+ getFlag(flagName) {
388
+ return __privateGet(this, _adapterState).flags[flagName];
389
+ }
390
+ updateClientContext(updatedContextProps) {
391
+ return __async(this, null, function* () {
392
+ const isAdapterConfigured = this.getIsConfigurationStatus(
393
+ _types.AdapterConfigurationStatus.Configured
394
+ );
395
+ _tinywarning2.default.call(void 0,
396
+ isAdapterConfigured,
397
+ "@flopflip/launchdarkly-adapter: adapter not configured. Client context can not be updated before."
398
+ );
399
+ if (!isAdapterConfigured) {
400
+ return Promise.reject(
401
+ new Error("Can not update client context: adapter not yet configured.")
402
+ );
403
+ }
404
+ return __privateGet(this, _changeClientContext).call(this, __spreadValues(__spreadValues({}, __privateGet(this, _adapterState).context), updatedContextProps));
405
+ });
406
+ }
407
+ };
408
+ _adapterState = new WeakMap();
409
+ _updateFlagsInAdapterState = new WeakMap();
410
+ _getIsAdapterUnsubscribed = new WeakMap();
411
+ _getIsFlagUnsubcribed = new WeakMap();
412
+ _getIsFlagLocked = new WeakMap();
413
+ _withoutUnsubscribedOrLockedFlags = new WeakMap();
414
+ _getIsAnonymousContext = new WeakMap();
415
+ _ensureContext = new WeakMap();
416
+ _initializeClient = new WeakMap();
417
+ _changeClientContext = new WeakMap();
418
+ _maybeUpdateFlagsInCache = new WeakMap();
419
+ _getInitialFlags = new WeakMap();
420
+ _didFlagChange = new WeakMap();
421
+ _setupFlagSubcription = new WeakMap();
422
+ var adapter = new LaunchDarklyAdapter();
423
+ _adapterutilities.exposeGlobally.call(void 0, adapter);
424
+
425
+ // src/index.ts
426
+ var version = "__@FLOPFLIP/VERSION_OF_RELEASE__";
427
+
428
+
429
+
430
+ exports.adapter = adapter; exports.version = version;
431
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/flopflip/flopflip/packages/launchdarkly-adapter/dist/index.cjs","../src/adapter.ts","../src/index.ts"],"names":["updatedFlags","flags"],"mappings":"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","file":"/home/runner/work/flopflip/flopflip/packages/launchdarkly-adapter/dist/index.cjs","sourcesContent":[null,"import {\n denormalizeFlagName,\n exposeGlobally,\n normalizeFlag,\n normalizeFlags,\n} from '@flopflip/adapter-utilities';\nimport { getCache } from '@flopflip/cache';\nimport {\n AdapterConfigurationStatus,\n AdapterInitializationStatus,\n AdapterSubscriptionStatus,\n type TAdapterEventHandlers,\n type TAdapterStatus,\n type TAdapterStatusChange,\n type TCacheIdentifiers,\n type TCacheModes,\n type TFlagName,\n type TFlagVariation,\n type TFlags,\n type TFlagsChange,\n type TLaunchDarklyAdapterArgs,\n type TLaunchDarklyAdapterInterface,\n type TUpdateFlagsOptions,\n adapterIdentifiers,\n cacheModes,\n} from '@flopflip/types';\nimport debounce from 'debounce-fn';\nimport {\n type LDClient,\n type LDContext,\n initialize as initializeLaunchDarklyClient,\n} from 'launchdarkly-js-client-sdk';\nimport isEqual from 'lodash/isEqual';\nimport mitt, { type Emitter } from 'mitt';\nimport warning from 'tiny-warning';\nimport { merge } from 'ts-deepmerge';\n\ntype TEmitterEvents = {\n flagsStateChange: TFlags;\n statusStateChange: Partial<TAdapterStatus>;\n};\n\ntype TLaunchDarklyAdapterState = {\n context?: LDContext;\n client?: LDClient;\n flags: TFlags;\n emitter: Emitter<TEmitterEvents>;\n lockedFlags: Set<TFlagName>;\n unsubscribedFlags: Set<TFlagName>;\n};\n\nclass LaunchDarklyAdapter implements TLaunchDarklyAdapterInterface {\n id: typeof adapterIdentifiers.launchdarkly;\n\n readonly #adapterState: TAdapterStatus & TLaunchDarklyAdapterState;\n\n constructor() {\n this.#adapterState = {\n subscriptionStatus: AdapterSubscriptionStatus.Subscribed,\n configurationStatus: AdapterConfigurationStatus.Unconfigured,\n context: undefined,\n client: undefined,\n flags: {},\n // Typings are incorrect and state that mitt is not callable.\n // Value of type 'MittStatic' is not callable. Did you mean to include 'new'\n emitter: mitt(),\n lockedFlags: new Set<TFlagName>(),\n unsubscribedFlags: new Set<TFlagName>(),\n };\n this.id = adapterIdentifiers.launchdarkly;\n }\n\n readonly #updateFlagsInAdapterState = (\n flags: TFlags,\n options?: TUpdateFlagsOptions\n ): void => {\n const updatedFlags = Object.entries(flags).reduce(\n (updatedFlags, [flagName, flagValue]) => {\n if (this.#getIsFlagLocked(flagName)) {\n return updatedFlags;\n }\n\n if (options?.lockFlags) {\n this.#adapterState.lockedFlags.add(flagName);\n }\n\n if (options?.unsubscribeFlags) {\n this.#adapterState.unsubscribedFlags.add(flagName);\n }\n\n const updated = {\n ...updatedFlags,\n [flagName]: flagValue,\n };\n\n return updated;\n },\n {}\n );\n\n this.#adapterState.flags = {\n ...this.#adapterState.flags,\n ...updatedFlags,\n };\n };\n\n readonly #getIsAdapterUnsubscribed = () =>\n this.#adapterState.subscriptionStatus ===\n AdapterSubscriptionStatus.Unsubscribed;\n\n readonly #getIsFlagUnsubcribed = (flagName: TFlagName) =>\n this.#adapterState.unsubscribedFlags.has(flagName);\n\n readonly #getIsFlagLocked = (flagName: TFlagName) =>\n this.#adapterState.lockedFlags.has(flagName);\n\n readonly #withoutUnsubscribedOrLockedFlags = (flags: TFlags) =>\n Object.fromEntries(\n Object.entries(flags).filter(\n ([flagName]) =>\n !this.#getIsFlagUnsubcribed(flagName) &&\n !this.#getIsFlagLocked(flagName)\n )\n );\n\n readonly #getIsAnonymousContext = (context: LDContext) => !context?.key;\n\n readonly #ensureContext = (context: LDContext) => {\n const isAnonymousContext = this.#getIsAnonymousContext(context);\n\n // NOTE: When marked `anonymous` the SDK will generate a unique key and cache it in local storage\n return merge(context, {\n key: isAnonymousContext ? undefined : context.key,\n anonymous: isAnonymousContext,\n });\n };\n\n readonly #initializeClient = (\n clientSideId: TLaunchDarklyAdapterArgs['sdk']['clientSideId'],\n context: LDContext,\n options: TLaunchDarklyAdapterArgs['sdk']['clientOptions']\n ) => initializeLaunchDarklyClient(clientSideId, context, options);\n\n readonly #changeClientContext = async (nextContext: LDContext) =>\n this.#adapterState.client?.identify\n ? this.#adapterState.client.identify(nextContext)\n : Promise.reject(\n new Error('Can not change user context: client not yet initialized.')\n );\n\n readonly #maybeUpdateFlagsInCache = async (\n flagsToCache: TFlags,\n cacheIdentifier?: TCacheIdentifiers\n ) => {\n if (cacheIdentifier) {\n const cache = await getCache(\n cacheIdentifier,\n adapterIdentifiers.launchdarkly,\n // NOTE: LDContextCommon is part of the type which we never use.\n this.#adapterState.context\n );\n\n const cachedFlags: TFlags = cache.get();\n\n cache.set({ ...cachedFlags, ...flagsToCache });\n }\n };\n\n readonly #getInitialFlags = async ({\n flags,\n throwOnInitializationFailure,\n cacheIdentifier,\n cacheMode,\n initializationTimeout,\n }: Pick<\n TLaunchDarklyAdapterArgs,\n | 'flags'\n | 'throwOnInitializationFailure'\n | 'cacheIdentifier'\n | 'cacheMode'\n | 'initializationTimeout'\n >): Promise<{\n flagsFromSdk?: TFlags;\n initializationStatus: AdapterInitializationStatus;\n }> => {\n if (this.#adapterState.client) {\n return this.#adapterState.client\n .waitForInitialization(initializationTimeout)\n .then(async () => {\n let flagsFromSdk: TFlags | undefined;\n\n if (this.#adapterState.client && !flags) {\n flagsFromSdk = this.#adapterState.client.allFlags();\n } else if (this.#adapterState.client && flags) {\n flagsFromSdk = {};\n\n for (const [requestedFlagName, defaultFlagValue] of Object.entries(\n flags\n )) {\n const denormalizedRequestedFlagName =\n denormalizeFlagName(requestedFlagName);\n flagsFromSdk[denormalizedRequestedFlagName] =\n this.#adapterState.client.variation(\n denormalizedRequestedFlagName,\n defaultFlagValue\n );\n }\n }\n\n if (flagsFromSdk) {\n const normalizedFlags = normalizeFlags(flagsFromSdk);\n\n await this.#maybeUpdateFlagsInCache(\n normalizedFlags,\n cacheIdentifier\n );\n\n const flags =\n this.#withoutUnsubscribedOrLockedFlags(normalizedFlags);\n\n this.#updateFlagsInAdapterState(flags);\n\n if (cacheMode !== cacheModes.lazy) {\n this.#adapterState.emitter.emit(\n 'flagsStateChange',\n this.#adapterState.flags\n );\n }\n }\n\n this.setConfigurationStatus(AdapterConfigurationStatus.Configured);\n\n return Promise.resolve({\n flagsFromSdk,\n initializationStatus: AdapterInitializationStatus.Succeeded,\n });\n })\n .catch(async () => {\n if (throwOnInitializationFailure) {\n return Promise.reject(\n new Error(\n '@flopflip/launchdarkly-adapter: adapter failed to initialize.'\n )\n );\n }\n\n console.warn(\n '@flopflip/launchdarkly-adapter: adapter failed to initialize.'\n );\n\n return Promise.resolve({\n flagsFromSdk: undefined,\n initializationStatus: AdapterInitializationStatus.Failed,\n });\n });\n }\n\n return Promise.reject(\n new Error(\n '@flopflip/launchdarkly-adapter: can not subscribe with non initialized client.'\n )\n );\n };\n\n readonly #didFlagChange = (\n flagName: TFlagName,\n nextFlagValue: TFlagVariation\n ) => {\n const previousFlagValue = this.getFlag(flagName);\n\n if (previousFlagValue === undefined) {\n return true;\n }\n\n return previousFlagValue !== nextFlagValue;\n };\n\n readonly #setupFlagSubcription = ({\n flagsFromSdk,\n flagsUpdateDelayMs,\n cacheIdentifier,\n cacheMode,\n }: {\n flagsFromSdk: TFlags;\n flagsUpdateDelayMs?: number;\n cacheIdentifier?: TCacheIdentifiers;\n cacheMode?: TCacheModes;\n }) => {\n for (const flagName in flagsFromSdk) {\n // Dispatch whenever a configured flag value changes\n if (Object.hasOwn(flagsFromSdk, flagName) && this.#adapterState.client) {\n this.#adapterState.client.on(\n `change:${flagName}`,\n async (flagValue) => {\n const [normalizedFlagName, normalizedFlagValue] = normalizeFlag(\n flagName,\n flagValue as TFlagVariation\n );\n\n await this.#maybeUpdateFlagsInCache(\n {\n [normalizedFlagName]: normalizedFlagValue,\n },\n cacheIdentifier\n );\n\n if (this.#getIsFlagUnsubcribed(normalizedFlagName)) {\n return;\n }\n\n // Sometimes the SDK flushes flag changes without a value having changed.\n if (!this.#didFlagChange(normalizedFlagName, normalizedFlagValue)) {\n return;\n }\n\n const updatedFlags: TFlags = {\n [normalizedFlagName]: normalizedFlagValue,\n };\n // NOTE: Adapter state needs to be updated outside of debounced-fn\n // so that no flag updates are lost.\n this.#updateFlagsInAdapterState(updatedFlags);\n\n const flushFlagsUpdate = () => {\n if (cacheMode === cacheModes.lazy) {\n return;\n }\n\n this.#adapterState.emitter.emit(\n 'flagsStateChange',\n this.#adapterState.flags\n );\n };\n\n const scheduleImmediately = { before: true, after: false };\n const scheduleTrailingEdge = { before: false, after: true };\n\n debounce(flushFlagsUpdate, {\n wait: flagsUpdateDelayMs,\n ...(flagsUpdateDelayMs\n ? scheduleTrailingEdge\n : scheduleImmediately),\n })();\n }\n );\n }\n }\n };\n\n // External. Flags are autolocked when updated.\n updateFlags = (flags: TFlags, options?: TUpdateFlagsOptions) => {\n this.#updateFlagsInAdapterState(flags, options);\n\n // ...and flush initial state of flags\n this.#adapterState.emitter.emit(\n 'flagsStateChange',\n this.#adapterState.flags\n );\n };\n\n async configure(\n adapterArgs: TLaunchDarklyAdapterArgs,\n adapterEventHandlers: TAdapterEventHandlers\n ) {\n const handleFlagsChange = (nextFlags: TFlagsChange['flags']) => {\n if (this.#getIsAdapterUnsubscribed()) {\n return;\n }\n\n adapterEventHandlers.onFlagsStateChange({\n flags: nextFlags,\n id: this.id,\n });\n };\n\n const handleStatusChange = (nextStatus: TAdapterStatusChange['status']) => {\n if (this.#getIsAdapterUnsubscribed()) {\n return;\n }\n\n adapterEventHandlers.onStatusStateChange({\n status: nextStatus,\n id: this.id,\n });\n };\n\n this.#adapterState.configurationStatus =\n AdapterConfigurationStatus.Configuring;\n\n this.#adapterState.emitter.on('flagsStateChange', handleFlagsChange);\n this.#adapterState.emitter.on('statusStateChange', handleStatusChange);\n\n this.#adapterState.emitter.emit('statusStateChange', {\n configurationStatus: this.#adapterState.configurationStatus,\n });\n\n const {\n sdk,\n context,\n flags,\n throwOnInitializationFailure = false,\n initializationTimeout = 2, // 2 seconds\n flagsUpdateDelayMs,\n } = adapterArgs;\n let cachedFlags: TFlags;\n\n this.#adapterState.context = this.#ensureContext(context);\n\n if (adapterArgs.cacheIdentifier) {\n const cache = await getCache(\n adapterArgs.cacheIdentifier,\n adapterIdentifiers.launchdarkly,\n this.#adapterState.context\n );\n\n cachedFlags = cache.get();\n\n if (cachedFlags) {\n this.#updateFlagsInAdapterState(cachedFlags);\n this.#adapterState.flags = cachedFlags;\n this.#adapterState.emitter.emit('flagsStateChange', cachedFlags);\n }\n }\n\n this.#adapterState.client = this.#initializeClient(\n sdk.clientSideId,\n this.#adapterState.context,\n sdk.clientOptions ?? {}\n );\n\n return this.#getInitialFlags({\n flags,\n throwOnInitializationFailure,\n cacheIdentifier: adapterArgs.cacheIdentifier,\n cacheMode: adapterArgs.cacheMode,\n initializationTimeout,\n }).then(({ flagsFromSdk, initializationStatus }) => {\n if (flagsFromSdk) {\n this.#setupFlagSubcription({\n flagsFromSdk,\n flagsUpdateDelayMs,\n cacheIdentifier: adapterArgs.cacheIdentifier,\n cacheMode: adapterArgs.cacheMode,\n });\n }\n\n return { initializationStatus };\n });\n }\n\n async reconfigure(\n adapterArgs: TLaunchDarklyAdapterArgs,\n _adapterEventHandlers: TAdapterEventHandlers\n ) {\n if (!this.getIsConfigurationStatus(AdapterConfigurationStatus.Configured)) {\n return Promise.reject(\n new Error(\n '@flopflip/launchdarkly-adapter: please configure adapter before reconfiguring.'\n )\n );\n }\n\n const nextContext = this.#ensureContext(adapterArgs.context);\n\n if (!isEqual(this.#adapterState.context, nextContext)) {\n if (adapterArgs.cacheIdentifier) {\n const cache = await getCache(\n adapterArgs.cacheIdentifier,\n adapterIdentifiers.launchdarkly,\n this.#adapterState.context\n );\n\n cache.unset();\n }\n\n this.#adapterState.context = nextContext;\n\n await this.#changeClientContext(this.#adapterState.context);\n }\n\n return Promise.resolve({\n initializationStatus: AdapterInitializationStatus.Succeeded,\n });\n }\n\n getIsConfigurationStatus(configurationStatus: AdapterConfigurationStatus) {\n return this.#adapterState.configurationStatus === configurationStatus;\n }\n\n setConfigurationStatus(nextConfigurationStatus: AdapterConfigurationStatus) {\n this.#adapterState.configurationStatus = nextConfigurationStatus;\n\n this.#adapterState.emitter.emit('statusStateChange', {\n configurationStatus: this.#adapterState.configurationStatus,\n });\n }\n\n getClient() {\n return this.#adapterState.client;\n }\n\n getFlag(flagName: TFlagName): TFlagVariation {\n return this.#adapterState.flags[flagName];\n }\n\n async updateClientContext(\n updatedContextProps: TLaunchDarklyAdapterArgs['context']\n ) {\n const isAdapterConfigured = this.getIsConfigurationStatus(\n AdapterConfigurationStatus.Configured\n );\n\n warning(\n isAdapterConfigured,\n '@flopflip/launchdarkly-adapter: adapter not configured. Client context can not be updated before.'\n );\n\n if (!isAdapterConfigured) {\n return Promise.reject(\n new Error('Can not update client context: adapter not yet configured.')\n );\n }\n\n return this.#changeClientContext({\n ...this.#adapterState.context,\n ...updatedContextProps,\n });\n }\n\n unsubscribe = () => {\n this.#adapterState.subscriptionStatus =\n AdapterSubscriptionStatus.Unsubscribed;\n };\n\n subscribe = () => {\n this.#adapterState.subscriptionStatus =\n AdapterSubscriptionStatus.Subscribed;\n };\n}\n\nconst adapter = new LaunchDarklyAdapter();\n\nexposeGlobally(adapter);\n\nexport { adapter };\n","const version = '__@FLOPFLIP/VERSION_OF_RELEASE__';\n\nexport { version };\nexport { adapter } from './adapter';\n"]}
@@ -1,5 +1,7 @@
1
- import { AdapterConfigurationStatus, adapterIdentifiers, AdapterInitializationStatus, type TAdapterEventHandlers, type TFlagName, type TFlags, type TFlagVariation, type TLaunchDarklyAdapterArgs, type TLaunchDarklyAdapterInterface, type TUpdateFlagsOptions } from '@flopflip/types';
2
- import { type LDClient } from 'launchdarkly-js-client-sdk';
1
+ import * as launchdarkly_js_sdk_common from 'launchdarkly-js-sdk-common';
2
+ import { TLaunchDarklyAdapterInterface, adapterIdentifiers, TFlags, TUpdateFlagsOptions, TLaunchDarklyAdapterArgs, TAdapterEventHandlers, AdapterInitializationStatus, AdapterConfigurationStatus, TFlagName, TFlagVariation } from '@flopflip/types';
3
+ import { LDClient } from 'launchdarkly-js-client-sdk';
4
+
3
5
  declare class LaunchDarklyAdapter implements TLaunchDarklyAdapterInterface {
4
6
  #private;
5
7
  id: typeof adapterIdentifiers.launchdarkly;
@@ -15,9 +17,12 @@ declare class LaunchDarklyAdapter implements TLaunchDarklyAdapterInterface {
15
17
  setConfigurationStatus(nextConfigurationStatus: AdapterConfigurationStatus): void;
16
18
  getClient(): LDClient | undefined;
17
19
  getFlag(flagName: TFlagName): TFlagVariation;
18
- updateClientContext(updatedContextProps: TLaunchDarklyAdapterArgs['context']): Promise<import("launchdarkly-js-sdk-common").LDFlagSet>;
20
+ updateClientContext(updatedContextProps: TLaunchDarklyAdapterArgs['context']): Promise<launchdarkly_js_sdk_common.LDFlagSet>;
19
21
  unsubscribe: () => void;
20
22
  subscribe: () => void;
21
23
  }
22
24
  declare const adapter: LaunchDarklyAdapter;
23
- export default adapter;
25
+
26
+ declare const version = "__@FLOPFLIP/VERSION_OF_RELEASE__";
27
+
28
+ export { adapter, version };
@@ -0,0 +1,28 @@
1
+ import * as launchdarkly_js_sdk_common from 'launchdarkly-js-sdk-common';
2
+ import { TLaunchDarklyAdapterInterface, adapterIdentifiers, TFlags, TUpdateFlagsOptions, TLaunchDarklyAdapterArgs, TAdapterEventHandlers, AdapterInitializationStatus, AdapterConfigurationStatus, TFlagName, TFlagVariation } from '@flopflip/types';
3
+ import { LDClient } from 'launchdarkly-js-client-sdk';
4
+
5
+ declare class LaunchDarklyAdapter implements TLaunchDarklyAdapterInterface {
6
+ #private;
7
+ id: typeof adapterIdentifiers.launchdarkly;
8
+ constructor();
9
+ updateFlags: (flags: TFlags, options?: TUpdateFlagsOptions) => void;
10
+ configure(adapterArgs: TLaunchDarklyAdapterArgs, adapterEventHandlers: TAdapterEventHandlers): Promise<{
11
+ initializationStatus: AdapterInitializationStatus;
12
+ }>;
13
+ reconfigure(adapterArgs: TLaunchDarklyAdapterArgs, _adapterEventHandlers: TAdapterEventHandlers): Promise<{
14
+ initializationStatus: AdapterInitializationStatus;
15
+ }>;
16
+ getIsConfigurationStatus(configurationStatus: AdapterConfigurationStatus): boolean;
17
+ setConfigurationStatus(nextConfigurationStatus: AdapterConfigurationStatus): void;
18
+ getClient(): LDClient | undefined;
19
+ getFlag(flagName: TFlagName): TFlagVariation;
20
+ updateClientContext(updatedContextProps: TLaunchDarklyAdapterArgs['context']): Promise<launchdarkly_js_sdk_common.LDFlagSet>;
21
+ unsubscribe: () => void;
22
+ subscribe: () => void;
23
+ }
24
+ declare const adapter: LaunchDarklyAdapter;
25
+
26
+ declare const version = "__@FLOPFLIP/VERSION_OF_RELEASE__";
27
+
28
+ export { adapter, version };