@launchdarkly/js-client-sdk-common 1.15.2 → 1.16.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 (42) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/cjs/LDClientImpl.d.ts +12 -3
  3. package/dist/cjs/LDClientImpl.d.ts.map +1 -1
  4. package/dist/cjs/LDEmitter.d.ts +1 -1
  5. package/dist/cjs/LDEmitter.d.ts.map +1 -1
  6. package/dist/cjs/api/LDPlugin.d.ts +16 -0
  7. package/dist/cjs/api/LDPlugin.d.ts.map +1 -0
  8. package/dist/cjs/api/index.d.ts +1 -0
  9. package/dist/cjs/api/index.d.ts.map +1 -1
  10. package/dist/cjs/context/createActiveContextTracker.d.ts +49 -0
  11. package/dist/cjs/context/createActiveContextTracker.d.ts.map +1 -0
  12. package/dist/cjs/flag-manager/FlagManager.d.ts +70 -1
  13. package/dist/cjs/flag-manager/FlagManager.d.ts.map +1 -1
  14. package/dist/cjs/flag-manager/FlagUpdater.d.ts +3 -2
  15. package/dist/cjs/flag-manager/FlagUpdater.d.ts.map +1 -1
  16. package/dist/cjs/index.cjs +185 -50
  17. package/dist/cjs/index.cjs.map +1 -1
  18. package/dist/cjs/index.d.ts +3 -2
  19. package/dist/cjs/index.d.ts.map +1 -1
  20. package/dist/cjs/plugins/safeRegisterDebugOverridePlugins.d.ts +12 -0
  21. package/dist/cjs/plugins/safeRegisterDebugOverridePlugins.d.ts.map +1 -0
  22. package/dist/esm/LDClientImpl.d.ts +12 -3
  23. package/dist/esm/LDClientImpl.d.ts.map +1 -1
  24. package/dist/esm/LDEmitter.d.ts +1 -1
  25. package/dist/esm/LDEmitter.d.ts.map +1 -1
  26. package/dist/esm/api/LDPlugin.d.ts +16 -0
  27. package/dist/esm/api/LDPlugin.d.ts.map +1 -0
  28. package/dist/esm/api/index.d.ts +1 -0
  29. package/dist/esm/api/index.d.ts.map +1 -1
  30. package/dist/esm/context/createActiveContextTracker.d.ts +49 -0
  31. package/dist/esm/context/createActiveContextTracker.d.ts.map +1 -0
  32. package/dist/esm/flag-manager/FlagManager.d.ts +70 -1
  33. package/dist/esm/flag-manager/FlagManager.d.ts.map +1 -1
  34. package/dist/esm/flag-manager/FlagUpdater.d.ts +3 -2
  35. package/dist/esm/flag-manager/FlagUpdater.d.ts.map +1 -1
  36. package/dist/esm/index.d.ts +3 -2
  37. package/dist/esm/index.d.ts.map +1 -1
  38. package/dist/esm/index.mjs +185 -51
  39. package/dist/esm/index.mjs.map +1 -1
  40. package/dist/esm/plugins/safeRegisterDebugOverridePlugins.d.ts +12 -0
  41. package/dist/esm/plugins/safeRegisterDebugOverridePlugins.d.ts.map +1 -0
  42. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import { Context, LDLogger, Platform } from '@launchdarkly/js-sdk-common';
1
+ import { Context, LDFlagValue, LDLogger, Platform } from '@launchdarkly/js-sdk-common';
2
2
  import { FlagsChangeCallback } from './FlagUpdater';
3
3
  import { ItemDescriptor } from './ItemDescriptor';
4
4
  /**
@@ -34,6 +34,16 @@ export interface FlagManager {
34
34
  * Asynchronously load cached values from persistence.
35
35
  */
36
36
  loadCached(context: Context): Promise<boolean>;
37
+ /**
38
+ * Updates in-memory storage with the specified flags without a context
39
+ * or persistent storage. Flags set in this way are considered emphemeral and
40
+ * should be replaced as soon as initialization is done.
41
+ *
42
+ * @param newFlags - cached flags
43
+ */
44
+ presetFlags(newFlags: {
45
+ [key: string]: ItemDescriptor;
46
+ }): void;
37
47
  /**
38
48
  * Update in-memory storage with the specified flags, but do not persistent them to cache
39
49
  * storage.
@@ -49,11 +59,59 @@ export interface FlagManager {
49
59
  * Unregister a flag change callback.
50
60
  */
51
61
  off(callback: FlagsChangeCallback): void;
62
+ /**
63
+ * Obtain debug override functions that allows plugins
64
+ * to manipulate the outcome of the flags managed by
65
+ * this manager
66
+ *
67
+ * @experimental This function is experimental and intended for use by LaunchDarkly tools at this time.
68
+ */
69
+ getDebugOverride?(): LDDebugOverride;
70
+ }
71
+ /**
72
+ * Debug interface for plugins that need to override flag values during development.
73
+ * This interface provides methods to temporarily override flag values that take
74
+ * precedence over the actual flag values from LaunchDarkly. These overrides are
75
+ * useful for testing, development, and debugging scenarios.
76
+ *
77
+ * @experimental This interface is experimental and intended for use by LaunchDarkly tools at this time.
78
+ * The API may change in future versions.
79
+ */
80
+ export interface LDDebugOverride {
81
+ /**
82
+ * Set an override value for a flag that takes precedence over the real flag value.
83
+ *
84
+ * @param flagKey The flag key.
85
+ * @param value The override value.
86
+ */
87
+ setOverride(flagKey: string, value: LDFlagValue): void;
88
+ /**
89
+ * Remove an override value for a flag, reverting to the real flag value.
90
+ *
91
+ * @param flagKey The flag key.
92
+ */
93
+ removeOverride(flagKey: string): void;
94
+ /**
95
+ * Clear all override values, reverting all flags to their real values.
96
+ */
97
+ clearAllOverrides(): void;
98
+ /**
99
+ * Get all currently active flag overrides.
100
+ *
101
+ * @returns
102
+ * An object containing all active overrides as key-value pairs,
103
+ * where keys are flag keys and values are the overridden flag values.
104
+ * Returns an empty object if no overrides are active.
105
+ */
106
+ getAllOverrides(): {
107
+ [key: string]: ItemDescriptor;
108
+ };
52
109
  }
53
110
  export default class DefaultFlagManager implements FlagManager {
54
111
  private _flagStore;
55
112
  private _flagUpdater;
56
113
  private _flagPersistencePromise;
114
+ private _overrides?;
57
115
  /**
58
116
  * @param platform implementation of various platform provided functionality
59
117
  * @param sdkKey that will be used to distinguish different environments
@@ -67,6 +125,9 @@ export default class DefaultFlagManager implements FlagManager {
67
125
  getAll(): {
68
126
  [key: string]: ItemDescriptor;
69
127
  };
128
+ presetFlags(newFlags: {
129
+ [key: string]: ItemDescriptor;
130
+ }): void;
70
131
  setBootstrap(context: Context, newFlags: {
71
132
  [key: string]: ItemDescriptor;
72
133
  }): void;
@@ -77,5 +138,13 @@ export default class DefaultFlagManager implements FlagManager {
77
138
  loadCached(context: Context): Promise<boolean>;
78
139
  on(callback: FlagsChangeCallback): void;
79
140
  off(callback: FlagsChangeCallback): void;
141
+ private _convertValueToOverrideDescripter;
142
+ setOverride(key: string, value: LDFlagValue): void;
143
+ removeOverride(flagKey: string): void;
144
+ clearAllOverrides(): void;
145
+ getAllOverrides(): {
146
+ [key: string]: ItemDescriptor;
147
+ };
148
+ getDebugOverride(): LDDebugOverride;
80
149
  }
81
150
  //# sourceMappingURL=FlagManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FlagManager.d.ts","sourceRoot":"","sources":["../../src/flag-manager/FlagManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAK1E,OAAoB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IAE7C;;OAEG;IACH,MAAM,IAAI;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAA;KAAE,CAAC;IAE5C;;;OAGG;IACH,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnF;;;OAGG;IACH,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9E;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/C;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAA;KAAE,GAAG,IAAI,CAAC;IAElF;;OAEG;IACH,EAAE,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAExC;;OAEG;IACH,GAAG,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,CAAC,OAAO,OAAO,kBAAmB,YAAW,WAAW;IAC5D,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,uBAAuB,CAA2B;IAE1D;;;;;;OAMG;gBAED,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,QAAQ,EAChB,WAAW,GAAE,MAAM,MAAyB;YAYhC,gBAAgB;IAoB9B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI5C,MAAM,IAAI;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAA;KAAE;IAI3C,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAA;KAAE,GAAG,IAAI;IAM3E,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlF,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAI7E,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAIpD,EAAE,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAIvC,GAAG,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;CAGzC"}
1
+ {"version":3,"file":"FlagManager.d.ts","sourceRoot":"","sources":["../../src/flag-manager/FlagManager.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { Context, LDLogger } from '@launchdarkly/js-sdk-common';
2
2
  import FlagStore from './FlagStore';
3
3
  import { ItemDescriptor } from './ItemDescriptor';
4
- export type FlagChangeType = 'init' | 'patch';
4
+ export type FlagChangeType = 'init' | 'patch' | 'override';
5
5
  /**
6
6
  * This callback indicates that the details associated with one or more flags
7
7
  * have changed.
@@ -24,9 +24,10 @@ export type FlagsChangeCallback = (context: Context, flagKeys: Array<string>, ty
24
24
  export default class FlagUpdater {
25
25
  private _flagStore;
26
26
  private _logger;
27
- private _activeContextKey;
27
+ private _activeContext;
28
28
  private _changeCallbacks;
29
29
  constructor(flagStore: FlagStore, logger: LDLogger);
30
+ handleFlagChanges(keys: string[], type: FlagChangeType): void;
30
31
  init(context: Context, newFlags: {
31
32
  [key: string]: ItemDescriptor;
32
33
  }): void;
@@ -1 +1 @@
1
- {"version":3,"file":"FlagUpdater.d.ts","sourceRoot":"","sources":["../../src/flag-manager/FlagUpdater.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,SAAS,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,EACvB,IAAI,EAAE,cAAc,KACjB,IAAI,CAAC;AAEV;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAC9B,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,iBAAiB,CAAqB;IAC9C,OAAO,CAAC,gBAAgB,CAAoC;gBAEhD,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ;IAKlD,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAA;KAAE;IAgBlE,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAA;KAAE;IAQxE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO;IAuBpE,EAAE,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAIvC,GAAG,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;CAMzC"}
1
+ {"version":3,"file":"FlagUpdater.d.ts","sourceRoot":"","sources":["../../src/flag-manager/FlagUpdater.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,SAAS,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;AAE3D;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,EACvB,IAAI,EAAE,cAAc,KACjB,IAAI,CAAC;AAEV;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAC9B,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,gBAAgB,CAAoC;gBAEhD,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ;IAKlD,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI;IAgB7D,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAA;KAAE;IAUlE,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAA;KAAE;IAQxE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO;IAiBpE,EAAE,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAIvC,GAAG,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;CAMzC"}
@@ -6,9 +6,10 @@ import LDClientImpl from './LDClientImpl';
6
6
  import LDEmitter, { EventName } from './LDEmitter';
7
7
  export * from '@launchdarkly/js-sdk-common';
8
8
  export * as platform from '@launchdarkly/js-sdk-common';
9
- export type { LDEvaluationDetail, LDEvaluationDetailTyped, LDClient, LDOptions, ConnectionMode, LDIdentifyOptions, Hook, HookMetadata, EvaluationSeriesContext, EvaluationSeriesData, IdentifySeriesContext, IdentifySeriesData, IdentifySeriesResult, IdentifySeriesStatus, TrackSeriesContext, LDInspection, LDIdentifyResult, LDIdentifySuccess, LDIdentifyError, LDIdentifyTimeout, LDIdentifyShed, LDClientIdentifyResult, } from './api';
9
+ export type { LDEvaluationDetail, LDEvaluationDetailTyped, LDClient, LDOptions, ConnectionMode, LDIdentifyOptions, Hook, HookMetadata, EvaluationSeriesContext, EvaluationSeriesData, IdentifySeriesContext, IdentifySeriesData, IdentifySeriesResult, IdentifySeriesStatus, TrackSeriesContext, LDInspection, LDIdentifyResult, LDIdentifySuccess, LDIdentifyError, LDIdentifyTimeout, LDIdentifyShed, LDClientIdentifyResult, LDPluginBase, } from './api';
10
10
  export type { DataManager, DataManagerFactory, ConnectionParams } from './DataManager';
11
- export type { FlagManager } from './flag-manager/FlagManager';
11
+ export type { FlagManager, LDDebugOverride } from './flag-manager/FlagManager';
12
+ export { safeRegisterDebugOverridePlugins } from './plugins/safeRegisterDebugOverridePlugins';
12
13
  export type { Configuration } from './configuration/Configuration';
13
14
  export type { LDEmitter };
14
15
  export type { ItemDescriptor } from './flag-manager/ItemDescriptor';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,gBAAgB,EAAE,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAClF,OAAO,yBAAyB,MAAM,wCAAwC,CAAC;AAC/E,OAAO,SAAS,EAAE,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,SAAS,EAAE,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEnD,cAAc,6BAA6B,CAAC;AAE5C,OAAO,KAAK,QAAQ,MAAM,6BAA6B,CAAC;AAMxD,YAAY,EACV,kBAAkB,EAClB,uBAAuB,EACvB,QAAQ,EACR,SAAS,EACT,cAAc,EACd,iBAAiB,EACjB,IAAI,EACJ,YAAY,EACZ,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,sBAAsB,GACvB,MAAM,OAAO,CAAC;AAEf,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACvF,YAAY,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,YAAY,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEnE,YAAY,EAAE,SAAS,EAAE,CAAC;AAC1B,YAAY,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,YAAY,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AAEpC,OAAO,EACL,gBAAgB,EAChB,yBAAyB,EACzB,YAAY,EACZ,uBAAuB,EACvB,eAAe,EACf,SAAS,IAAI,kBAAkB,GAChC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,gBAAgB,EAAE,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAClF,OAAO,yBAAyB,MAAM,wCAAwC,CAAC;AAC/E,OAAO,SAAS,EAAE,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,SAAS,EAAE,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEnD,cAAc,6BAA6B,CAAC;AAE5C,OAAO,KAAK,QAAQ,MAAM,6BAA6B,CAAC;AAMxD,YAAY,EACV,kBAAkB,EAClB,uBAAuB,EACvB,QAAQ,EACR,SAAS,EACT,cAAc,EACd,iBAAiB,EACjB,IAAI,EACJ,YAAY,EACZ,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,YAAY,GACb,MAAM,OAAO,CAAC;AAEf,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACvF,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAAE,gCAAgC,EAAE,MAAM,4CAA4C,CAAC;AAC9F,YAAY,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEnE,YAAY,EAAE,SAAS,EAAE,CAAC;AAC1B,YAAY,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,YAAY,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AAEpC,OAAO,EACL,gBAAgB,EAChB,yBAAyB,EACzB,YAAY,EACZ,uBAAuB,EACvB,eAAe,EACf,SAAS,IAAI,kBAAkB,GAChC,CAAC"}
@@ -520,6 +520,38 @@ const addAutoEnv = async (context, platform, config) => {
520
520
  return context;
521
521
  };
522
522
 
523
+ function createActiveContextTracker() {
524
+ let unwrappedContext;
525
+ let context;
526
+ return {
527
+ set(_unwrappedContext, _context) {
528
+ unwrappedContext = _unwrappedContext;
529
+ context = _context;
530
+ },
531
+ getContext() {
532
+ return context;
533
+ },
534
+ getUnwrappedContext() {
535
+ return unwrappedContext;
536
+ },
537
+ newIdentificationPromise() {
538
+ let res;
539
+ let rej;
540
+ const basePromise = new Promise((resolve, reject) => {
541
+ res = resolve;
542
+ rej = reject;
543
+ });
544
+ return { identifyPromise: basePromise, identifyResolve: res, identifyReject: rej };
545
+ },
546
+ hasContext() {
547
+ return context !== undefined;
548
+ },
549
+ hasValidContext() {
550
+ return this.hasContext() && context.valid;
551
+ },
552
+ };
553
+ }
554
+
523
555
  const { isLegacyUser, isMultiKind, isSingleKind } = internal;
524
556
  /**
525
557
  * This is the root ensureKey function. All other ensureKey functions reduce to this.
@@ -868,30 +900,38 @@ class FlagUpdater {
868
900
  this._flagStore = flagStore;
869
901
  this._logger = logger;
870
902
  }
871
- init(context, newFlags) {
872
- this._activeContextKey = context.canonicalKey;
873
- const oldFlags = this._flagStore.getAll();
874
- this._flagStore.init(newFlags);
875
- const changed = calculateChangedKeys(oldFlags, newFlags);
876
- if (changed.length > 0) {
903
+ handleFlagChanges(keys, type) {
904
+ if (this._activeContext) {
877
905
  this._changeCallbacks.forEach((callback) => {
878
906
  try {
879
- callback(context, changed, 'init');
907
+ callback(this._activeContext, keys, type);
880
908
  }
881
909
  catch (err) {
882
910
  /* intentionally empty */
883
911
  }
884
912
  });
885
913
  }
914
+ else {
915
+ this._logger.warn('Received a change event without an active context. Changes will not be propagated.');
916
+ }
917
+ }
918
+ init(context, newFlags) {
919
+ this._activeContext = context;
920
+ const oldFlags = this._flagStore.getAll();
921
+ this._flagStore.init(newFlags);
922
+ const changed = calculateChangedKeys(oldFlags, newFlags);
923
+ if (changed.length > 0) {
924
+ this.handleFlagChanges(changed, 'init');
925
+ }
886
926
  }
887
927
  initCached(context, newFlags) {
888
- if (this._activeContextKey === context.canonicalKey) {
928
+ if (this._activeContext?.canonicalKey === context.canonicalKey) {
889
929
  return;
890
930
  }
891
931
  this.init(context, newFlags);
892
932
  }
893
933
  upsert(context, key, item) {
894
- if (this._activeContextKey !== context.canonicalKey) {
934
+ if (this._activeContext?.canonicalKey !== context.canonicalKey) {
895
935
  this._logger.warn('Received an update for an inactive context.');
896
936
  return false;
897
937
  }
@@ -901,14 +941,7 @@ class FlagUpdater {
901
941
  return false;
902
942
  }
903
943
  this._flagStore.insertOrUpdate(key, item);
904
- this._changeCallbacks.forEach((callback) => {
905
- try {
906
- callback(context, [key], 'patch');
907
- }
908
- catch (err) {
909
- /* intentionally empty */
910
- }
911
- });
944
+ this.handleFlagChanges([key], 'patch');
912
945
  return true;
913
946
  }
914
947
  on(callback) {
@@ -940,11 +973,26 @@ class DefaultFlagManager {
940
973
  return new FlagPersistence(platform, environmentNamespace, maxCachedContexts, this._flagStore, this._flagUpdater, logger, timeStamper);
941
974
  }
942
975
  get(key) {
976
+ if (this._overrides && Object.prototype.hasOwnProperty.call(this._overrides, key)) {
977
+ return this._convertValueToOverrideDescripter(this._overrides[key]);
978
+ }
943
979
  return this._flagStore.get(key);
944
980
  }
945
981
  getAll() {
982
+ if (this._overrides) {
983
+ return {
984
+ ...this._flagStore.getAll(),
985
+ ...Object.entries(this._overrides).reduce((acc, [key, value]) => {
986
+ acc[key] = this._convertValueToOverrideDescripter(value);
987
+ return acc;
988
+ }, {}),
989
+ };
990
+ }
946
991
  return this._flagStore.getAll();
947
992
  }
993
+ presetFlags(newFlags) {
994
+ this._flagStore.init(newFlags);
995
+ }
948
996
  setBootstrap(context, newFlags) {
949
997
  // Bypasses the persistence as we do not want to put these flags into any cache.
950
998
  // Generally speaking persistence likely *SHOULD* be disabled when using bootstrap.
@@ -965,6 +1013,58 @@ class DefaultFlagManager {
965
1013
  off(callback) {
966
1014
  this._flagUpdater.off(callback);
967
1015
  }
1016
+ _convertValueToOverrideDescripter(value) {
1017
+ return {
1018
+ flag: {
1019
+ value,
1020
+ version: 0,
1021
+ },
1022
+ version: 0,
1023
+ };
1024
+ }
1025
+ setOverride(key, value) {
1026
+ if (!this._overrides) {
1027
+ this._overrides = {};
1028
+ }
1029
+ this._overrides[key] = value;
1030
+ this._flagUpdater.handleFlagChanges([key], 'override');
1031
+ }
1032
+ removeOverride(flagKey) {
1033
+ if (!this._overrides || !Object.prototype.hasOwnProperty.call(this._overrides, flagKey)) {
1034
+ return; // No override to remove
1035
+ }
1036
+ delete this._overrides[flagKey];
1037
+ // If no more overrides, reset to undefined for performance
1038
+ if (Object.keys(this._overrides).length === 0) {
1039
+ this._overrides = undefined;
1040
+ }
1041
+ this._flagUpdater.handleFlagChanges([flagKey], 'override');
1042
+ }
1043
+ clearAllOverrides() {
1044
+ if (this._overrides) {
1045
+ const clearedOverrides = { ...this._overrides };
1046
+ this._overrides = undefined; // Reset to undefined
1047
+ this._flagUpdater.handleFlagChanges(Object.keys(clearedOverrides), 'override');
1048
+ }
1049
+ }
1050
+ getAllOverrides() {
1051
+ if (!this._overrides) {
1052
+ return {};
1053
+ }
1054
+ const result = {};
1055
+ Object.entries(this._overrides).forEach(([key, value]) => {
1056
+ result[key] = this._convertValueToOverrideDescripter(value);
1057
+ });
1058
+ return result;
1059
+ }
1060
+ getDebugOverride() {
1061
+ return {
1062
+ setOverride: this.setOverride.bind(this),
1063
+ removeOverride: this.removeOverride.bind(this),
1064
+ clearAllOverrides: this.clearAllOverrides.bind(this),
1065
+ getAllOverrides: this.getAllOverrides.bind(this),
1066
+ };
1067
+ }
968
1068
  }
969
1069
 
970
1070
  const UNKNOWN_HOOK_NAME = 'unknown hook';
@@ -1327,6 +1427,7 @@ class LDClientImpl {
1327
1427
  this.sdkKey = sdkKey;
1328
1428
  this.autoEnvAttributes = autoEnvAttributes;
1329
1429
  this.platform = platform;
1430
+ this._activeContextTracker = createActiveContextTracker();
1330
1431
  this._highTimeoutThreshold = 15;
1331
1432
  this._eventFactoryDefault = new EventFactory(false);
1332
1433
  this._eventFactoryWithReasons = new EventFactory(true);
@@ -1401,19 +1502,20 @@ class LDClientImpl {
1401
1502
  // code. We are returned the unchecked context so that if a consumer identifies with an invalid context
1402
1503
  // and then calls getContext, they get back the same context they provided, without any assertion about
1403
1504
  // validity.
1404
- return this._uncheckedContext ? clone(this._uncheckedContext) : undefined;
1505
+ return this._activeContextTracker.hasContext()
1506
+ ? clone(this._activeContextTracker.getUnwrappedContext())
1507
+ : undefined;
1405
1508
  }
1406
1509
  getInternalContext() {
1407
- return this._checkedContext;
1408
- }
1409
- _createIdentifyPromise() {
1410
- let res;
1411
- let rej;
1412
- const basePromise = new Promise((resolve, reject) => {
1413
- res = resolve;
1414
- rej = reject;
1415
- });
1416
- return { identifyPromise: basePromise, identifyResolve: res, identifyReject: rej };
1510
+ return this._activeContextTracker.getContext();
1511
+ }
1512
+ /**
1513
+ * Preset flags are used to set the flags before the client is initialized. This is useful for
1514
+ * when client has precached flags that are ready to evaluate without full initialization.
1515
+ * @param newFlags - The flags to preset.
1516
+ */
1517
+ presetFlags(newFlags) {
1518
+ this._flagManager.presetFlags(newFlags);
1417
1519
  }
1418
1520
  /**
1419
1521
  * Identifies a context to LaunchDarkly. See {@link LDClient.identify}.
@@ -1489,11 +1591,10 @@ class LDClientImpl {
1489
1591
  this.emitter.emit('error', context, error);
1490
1592
  return Promise.reject(error);
1491
1593
  }
1492
- this._uncheckedContext = context;
1493
- this._checkedContext = checkedContext;
1494
- this._eventProcessor?.sendEvent(this._eventFactoryDefault.identifyEvent(this._checkedContext));
1495
- const { identifyPromise, identifyResolve, identifyReject } = this._createIdentifyPromise();
1496
- this.logger.debug(`Identifying ${JSON.stringify(this._checkedContext)}`);
1594
+ this._activeContextTracker.set(context, checkedContext);
1595
+ this._eventProcessor?.sendEvent(this._eventFactoryDefault.identifyEvent(checkedContext));
1596
+ const { identifyPromise, identifyResolve, identifyReject } = this._activeContextTracker.newIdentificationPromise();
1597
+ this.logger.debug(`Identifying ${JSON.stringify(checkedContext)}`);
1497
1598
  await this.dataManager.identify(identifyResolve, identifyReject, checkedContext, identifyOptions);
1498
1599
  return identifyPromise;
1499
1600
  },
@@ -1516,6 +1617,7 @@ class LDClientImpl {
1516
1617
  if (res.status === 'shed') {
1517
1618
  return { status: 'shed' };
1518
1619
  }
1620
+ this.emitter.emit('initialized');
1519
1621
  return { status: 'completed' };
1520
1622
  });
1521
1623
  if (noTimeout) {
@@ -1535,7 +1637,7 @@ class LDClientImpl {
1535
1637
  this.emitter.off(eventName, listener);
1536
1638
  }
1537
1639
  track(key, data, metricValue) {
1538
- if (!this._checkedContext || !this._checkedContext.valid) {
1640
+ if (!this._activeContextTracker.hasValidContext()) {
1539
1641
  this.logger.warn(ClientMessages.MissingContextKeyNoEvent);
1540
1642
  return;
1541
1643
  }
@@ -1543,37 +1645,46 @@ class LDClientImpl {
1543
1645
  if (metricValue !== undefined && !TypeValidators.Number.is(metricValue)) {
1544
1646
  this.logger?.warn(ClientMessages.invalidMetricValue(typeof metricValue));
1545
1647
  }
1546
- this._eventProcessor?.sendEvent(this._config.trackEventModifier(this._eventFactoryDefault.customEvent(key, this._checkedContext, data, metricValue)));
1648
+ this._eventProcessor?.sendEvent(this._config.trackEventModifier(this._eventFactoryDefault.customEvent(key, this._activeContextTracker.getContext(), data, metricValue)));
1547
1649
  this._hookRunner.afterTrack({
1548
1650
  key,
1549
1651
  // The context is pre-checked above, so we know it can be unwrapped.
1550
- context: this._uncheckedContext,
1652
+ context: this._activeContextTracker.getUnwrappedContext(),
1551
1653
  data,
1552
1654
  metricValue,
1553
1655
  });
1554
1656
  }
1555
1657
  _variationInternal(flagKey, defaultValue, eventFactory, typeChecker) {
1556
- if (!this._uncheckedContext) {
1557
- this.logger.debug(ClientMessages.MissingContextKeyNoEvent);
1558
- return createErrorEvaluationDetail(ErrorKinds.UserNotSpecified, defaultValue);
1559
- }
1560
- const evalContext = Context.fromLDContext(this._uncheckedContext);
1658
+ // We are letting evaulations happen without a context. The main case for this
1659
+ // is when cached data is loaded, but the client is not fully initialized. In this
1660
+ // case, we will write out a warning for each evaluation attempt.
1661
+ // NOTE: we will be changing this behavior soon once we have a tracker on the
1662
+ // client initialization state.
1663
+ const hasContext = this._activeContextTracker.hasContext();
1664
+ if (!hasContext) {
1665
+ this.logger?.warn('Flag evaluation called before client is fully initialized, data from this evaulation could be stale.');
1666
+ }
1667
+ const evalContext = this._activeContextTracker.getContext();
1561
1668
  const foundItem = this._flagManager.get(flagKey);
1562
1669
  if (foundItem === undefined || foundItem.flag.deleted) {
1563
1670
  const defVal = defaultValue ?? null;
1564
1671
  const error = new LDClientError(`Unknown feature flag "${flagKey}"; returning default value ${defVal}.`);
1565
- this.emitter.emit('error', this._uncheckedContext, error);
1566
- this._eventProcessor?.sendEvent(this._eventFactoryDefault.unknownFlagEvent(flagKey, defVal, evalContext));
1672
+ this.emitter.emit('error', this._activeContextTracker.getUnwrappedContext(), error);
1673
+ if (hasContext) {
1674
+ this._eventProcessor?.sendEvent(this._eventFactoryDefault.unknownFlagEvent(flagKey, defVal, evalContext));
1675
+ }
1567
1676
  return createErrorEvaluationDetail(ErrorKinds.FlagNotFound, defaultValue);
1568
1677
  }
1569
1678
  const { reason, value, variation, prerequisites } = foundItem.flag;
1570
1679
  if (typeChecker) {
1571
1680
  const [matched, type] = typeChecker(value);
1572
1681
  if (!matched) {
1573
- this._eventProcessor?.sendEvent(eventFactory.evalEventClient(flagKey, defaultValue, // track default value on type errors
1574
- defaultValue, foundItem.flag, evalContext, reason));
1682
+ if (hasContext) {
1683
+ this._eventProcessor?.sendEvent(eventFactory.evalEventClient(flagKey, defaultValue, // track default value on type errors
1684
+ defaultValue, foundItem.flag, evalContext, reason));
1685
+ }
1575
1686
  const error = new LDClientError(`Wrong type "${type}" for feature flag "${flagKey}"; returning default value`);
1576
- this.emitter.emit('error', this._uncheckedContext, error);
1687
+ this.emitter.emit('error', this._activeContextTracker.getUnwrappedContext(), error);
1577
1688
  return createErrorEvaluationDetail(ErrorKinds.WrongType, defaultValue);
1578
1689
  }
1579
1690
  }
@@ -1585,18 +1696,20 @@ class LDClientImpl {
1585
1696
  prerequisites?.forEach((prereqKey) => {
1586
1697
  this._variationInternal(prereqKey, undefined, this._eventFactoryDefault);
1587
1698
  });
1588
- this._eventProcessor?.sendEvent(eventFactory.evalEventClient(flagKey, value, defaultValue, foundItem.flag, evalContext, reason));
1699
+ if (hasContext) {
1700
+ this._eventProcessor?.sendEvent(eventFactory.evalEventClient(flagKey, value, defaultValue, foundItem.flag, evalContext, reason));
1701
+ }
1589
1702
  return successDetail;
1590
1703
  }
1591
1704
  variation(flagKey, defaultValue) {
1592
- const { value } = this._hookRunner.withEvaluation(flagKey, this._uncheckedContext, defaultValue, () => this._variationInternal(flagKey, defaultValue, this._eventFactoryDefault));
1705
+ const { value } = this._hookRunner.withEvaluation(flagKey, this._activeContextTracker.getUnwrappedContext(), defaultValue, () => this._variationInternal(flagKey, defaultValue, this._eventFactoryDefault));
1593
1706
  return value;
1594
1707
  }
1595
1708
  variationDetail(flagKey, defaultValue) {
1596
- return this._hookRunner.withEvaluation(flagKey, this._uncheckedContext, defaultValue, () => this._variationInternal(flagKey, defaultValue, this._eventFactoryWithReasons));
1709
+ return this._hookRunner.withEvaluation(flagKey, this._activeContextTracker.getUnwrappedContext(), defaultValue, () => this._variationInternal(flagKey, defaultValue, this._eventFactoryWithReasons));
1597
1710
  }
1598
1711
  _typedEval(key, defaultValue, eventFactory, typeChecker) {
1599
- return this._hookRunner.withEvaluation(key, this._uncheckedContext, defaultValue, () => this._variationInternal(key, defaultValue, eventFactory, typeChecker));
1712
+ return this._hookRunner.withEvaluation(key, this._activeContextTracker.getUnwrappedContext(), defaultValue, () => this._variationInternal(key, defaultValue, eventFactory, typeChecker));
1600
1713
  }
1601
1714
  boolVariation(key, defaultValue) {
1602
1715
  return this._typedEval(key, defaultValue, this._eventFactoryDefault, (value) => [
@@ -1678,6 +1791,9 @@ class LDClientImpl {
1678
1791
  sendEvent(event) {
1679
1792
  this._eventProcessor?.sendEvent(event);
1680
1793
  }
1794
+ getDebugOverrides() {
1795
+ return this._flagManager.getDebugOverride?.();
1796
+ }
1681
1797
  _handleInspectionChanged(flagKeys, type) {
1682
1798
  if (!this._inspectorManager.hasInspectors()) {
1683
1799
  return;
@@ -1710,6 +1826,24 @@ class LDClientImpl {
1710
1826
  }
1711
1827
  }
1712
1828
 
1829
+ /**
1830
+ * Safe register debug override plugins.
1831
+ *
1832
+ * @param logger The logger to use for logging errors.
1833
+ * @param debugOverride The debug override to register.
1834
+ * @param plugins The plugins to register.
1835
+ */
1836
+ function safeRegisterDebugOverridePlugins(logger, debugOverride, plugins) {
1837
+ plugins.forEach((plugin) => {
1838
+ try {
1839
+ plugin.registerDebug?.(debugOverride);
1840
+ }
1841
+ catch (error) {
1842
+ logger.error(`Exception thrown registering plugin ${internal.safeGetName(logger, plugin)}.`);
1843
+ }
1844
+ });
1845
+ }
1846
+
1713
1847
  class DataSourceEventHandler {
1714
1848
  constructor(_flagManager, _statusManager, _logger) {
1715
1849
  this._flagManager = _flagManager;
@@ -2185,5 +2319,5 @@ class BaseDataManager {
2185
2319
  }
2186
2320
  }
2187
2321
 
2188
- export { BaseDataManager, DataSourceState, LDClientImpl, Requestor, makeRequestor };
2322
+ export { BaseDataManager, DataSourceState, LDClientImpl, Requestor, makeRequestor, safeRegisterDebugOverridePlugins };
2189
2323
  //# sourceMappingURL=index.mjs.map