@launchdarkly/toolbar 2.5.3-beta.1 → 2.6.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/cdn/toolbar.min.js +65 -65
  2. package/dist/core/tests/mocks/providers.d.ts +132 -0
  3. package/dist/core/ui/Toolbar/components/new/AnalyticsConsentToast/AnalyticsConsentToast.d.ts +5 -0
  4. package/dist/core/ui/Toolbar/components/new/AnalyticsConsentToast/AnalyticsConsentToast.module.css.d.ts +13 -0
  5. package/dist/core/ui/Toolbar/components/new/AnalyticsConsentToast/index.d.ts +1 -0
  6. package/dist/core/ui/Toolbar/components/new/Contexts/ContextItem.d.ts +2 -2
  7. package/dist/core/ui/Toolbar/components/new/Settings/Privacy/PrivacySettings.d.ts +1 -0
  8. package/dist/core/ui/Toolbar/components/new/Settings/index.d.ts +1 -1
  9. package/dist/core/ui/Toolbar/components/new/types.d.ts +1 -1
  10. package/dist/core/ui/Toolbar/context/api/ContextsProvider.d.ts +7 -7
  11. package/dist/core/ui/Toolbar/context/state/ToolbarStateProvider.d.ts +6 -0
  12. package/dist/core/ui/Toolbar/context/telemetry/AnalyticsPreferencesProvider.d.ts +14 -0
  13. package/dist/core/ui/Toolbar/context/telemetry/index.d.ts +1 -0
  14. package/dist/core/ui/Toolbar/types/ldApi.d.ts +0 -7
  15. package/dist/core/ui/Toolbar/utils/context.d.ts +27 -8
  16. package/dist/core/ui/Toolbar/utils/localStorage.d.ts +17 -7
  17. package/dist/core/utils/analytics.d.ts +6 -1
  18. package/dist/index.cjs +1 -1
  19. package/dist/js/index.js +1 -1
  20. package/dist/js/plugins.js +446 -0
  21. package/dist/js/plugins.js.map +1 -0
  22. package/dist/js/react.js +86 -0
  23. package/dist/js/react.js.map +1 -0
  24. package/dist/js/types-entry.js +0 -0
  25. package/dist/plugins.cjs +483 -0
  26. package/dist/plugins.cjs.map +1 -0
  27. package/dist/plugins.d.ts +21 -0
  28. package/dist/react.cjs +123 -0
  29. package/dist/react.cjs.map +1 -0
  30. package/dist/react.d.ts +25 -0
  31. package/dist/types-entry.cjs +20 -0
  32. package/dist/types-entry.cjs.map +1 -0
  33. package/dist/types-entry.d.ts +12 -0
  34. package/package.json +47 -4
  35. package/dist/core/ui/Toolbar/components/new/Settings/SettingsContent.d.ts +0 -1
@@ -0,0 +1,483 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ EventInterceptionPlugin: ()=>EventInterceptionPlugin,
28
+ FlagOverridePlugin: ()=>FlagOverridePlugin
29
+ });
30
+ const DEFAULT_STORAGE_NAMESPACE = 'ld-flag-override';
31
+ class FlagOverridePlugin {
32
+ debugOverride;
33
+ config;
34
+ ldClient = null;
35
+ constructor(config = {}){
36
+ this.config = {
37
+ storageNamespace: config.storageNamespace ?? DEFAULT_STORAGE_NAMESPACE
38
+ };
39
+ }
40
+ getMetadata() {
41
+ return {
42
+ name: 'FlagOverridePlugin'
43
+ };
44
+ }
45
+ getHooks(_metadata) {
46
+ return [];
47
+ }
48
+ register(ldClient) {
49
+ this.ldClient = ldClient;
50
+ }
51
+ registerDebug(debugOverride) {
52
+ this.debugOverride = debugOverride;
53
+ this.loadExistingOverrides();
54
+ }
55
+ loadExistingOverrides() {
56
+ if (!this.debugOverride) return;
57
+ const storage = this.getStorage();
58
+ if (!storage) return;
59
+ try {
60
+ for(let i = 0; i < storage.length; i++){
61
+ const key = storage.key(i);
62
+ if (!key?.startsWith(this.config.storageNamespace + ':')) continue;
63
+ const storedValue = storage.getItem(key);
64
+ if (storedValue) try {
65
+ const value = JSON.parse(storedValue);
66
+ const flagKey = key.replace(this.config.storageNamespace + ':', '');
67
+ this.debugOverride.setOverride(flagKey, value);
68
+ } catch {
69
+ console.warn('flagOverridePlugin: Invalid stored value for', key);
70
+ storage.removeItem(key);
71
+ }
72
+ }
73
+ } catch (error) {
74
+ console.error('flagOverridePlugin: Error loading existing overrides:', error);
75
+ }
76
+ }
77
+ setOverride(flagKey, value) {
78
+ if (!this.debugOverride) return void console.warn('flagOverridePlugin: Debug interface not available');
79
+ if (!flagKey || 'string' != typeof flagKey) return void console.error('flagOverridePlugin: Invalid flag key:', flagKey);
80
+ if (void 0 === value) return void console.error('flagOverridePlugin: Cannot set undefined value for flag override');
81
+ try {
82
+ this.persistOverride(flagKey, value);
83
+ this.debugOverride.setOverride(flagKey, value);
84
+ } catch (error) {
85
+ console.error('flagOverridePlugin: Failed to set override:', error);
86
+ }
87
+ }
88
+ removeOverride(flagKey) {
89
+ if (!this.debugOverride) return void console.warn('flagOverridePlugin: Debug interface not available');
90
+ if (!flagKey || 'string' != typeof flagKey) return void console.error('flagOverridePlugin: Invalid flag key:', flagKey);
91
+ try {
92
+ this.removePersistedOverride(flagKey);
93
+ this.debugOverride.removeOverride(flagKey);
94
+ } catch (error) {
95
+ console.error('flagOverridePlugin: Failed to remove override:', error);
96
+ }
97
+ }
98
+ clearAllOverrides() {
99
+ if (!this.debugOverride) return void console.warn('flagOverridePlugin: Debug interface not available');
100
+ try {
101
+ this.clearPersistedOverrides();
102
+ this.debugOverride.clearAllOverrides();
103
+ } catch (error) {
104
+ console.error('flagOverridePlugin: Failed to clear overrides:', error);
105
+ }
106
+ }
107
+ getAllOverrides() {
108
+ if (!this.debugOverride) {
109
+ console.warn('flagOverridePlugin: Debug interface not available');
110
+ return {};
111
+ }
112
+ try {
113
+ return this.debugOverride.getAllOverrides();
114
+ } catch (error) {
115
+ console.error('flagOverridePlugin: Failed to get overrides:', error);
116
+ return {};
117
+ }
118
+ }
119
+ getClient() {
120
+ return this.ldClient;
121
+ }
122
+ getStorage() {
123
+ if ('undefined' == typeof window) return null;
124
+ return window.localStorage;
125
+ }
126
+ persistOverride(flagKey, value) {
127
+ const storage = this.getStorage();
128
+ if (!storage) return;
129
+ try {
130
+ const storageKey = `${this.config.storageNamespace}:${flagKey}`;
131
+ storage.setItem(storageKey, JSON.stringify(value));
132
+ } catch (error) {
133
+ console.error('flagOverridePlugin: Failed to persist override:', error);
134
+ }
135
+ }
136
+ removePersistedOverride(flagKey) {
137
+ const storage = this.getStorage();
138
+ if (!storage) return;
139
+ try {
140
+ const storageKey = `${this.config.storageNamespace}:${flagKey}`;
141
+ storage.removeItem(storageKey);
142
+ } catch (error) {
143
+ console.error('flagOverridePlugin: Failed to remove persisted override:', error);
144
+ }
145
+ }
146
+ clearPersistedOverrides() {
147
+ const storage = this.getStorage();
148
+ if (!storage) return;
149
+ try {
150
+ const keysToRemove = [];
151
+ const prefix = this.config.storageNamespace + ':';
152
+ for(let i = 0; i < storage.length; i++){
153
+ const key = storage.key(i);
154
+ if (key?.startsWith(prefix)) keysToRemove.push(key);
155
+ }
156
+ keysToRemove.forEach((key)=>storage.removeItem(key));
157
+ } catch (error) {
158
+ console.error('flagOverridePlugin: Failed to clear persisted overrides:', error);
159
+ }
160
+ }
161
+ }
162
+ const DEFAULT_MAX_EVENTS = 100;
163
+ class EventStore {
164
+ events = [];
165
+ listeners = new Set();
166
+ maxEvents;
167
+ constructor(config = {}){
168
+ this.maxEvents = config.maxEvents ?? DEFAULT_MAX_EVENTS;
169
+ }
170
+ addEvent(event) {
171
+ try {
172
+ this.events.push(event);
173
+ if (this.events.length > this.maxEvents) this.events.splice(0, this.events.length - this.maxEvents);
174
+ this.notifyListeners();
175
+ } catch (error) {
176
+ console.warn('Event store error:', error);
177
+ }
178
+ }
179
+ getEvents() {
180
+ return [
181
+ ...this.events
182
+ ];
183
+ }
184
+ subscribe(listener) {
185
+ this.listeners.add(listener);
186
+ listener();
187
+ return ()=>this.listeners.delete(listener);
188
+ }
189
+ clear() {
190
+ this.events = [];
191
+ this.notifyListeners();
192
+ }
193
+ destroy() {
194
+ this.listeners.clear();
195
+ this.events = [];
196
+ }
197
+ notifyListeners() {
198
+ this.listeners.forEach((listener)=>{
199
+ try {
200
+ listener();
201
+ } catch (error) {
202
+ console.warn('Listener error:', error);
203
+ }
204
+ });
205
+ }
206
+ }
207
+ class AfterTrackHook {
208
+ config;
209
+ idCounter = 0;
210
+ constructor(config = {}){
211
+ this.config = {
212
+ filter: config.filter,
213
+ onNewEvent: config.onNewEvent
214
+ };
215
+ }
216
+ getMetadata() {
217
+ return {
218
+ name: 'AfterTrackHook'
219
+ };
220
+ }
221
+ afterTrack(hookContext) {
222
+ try {
223
+ const syntheticContext = {
224
+ kind: 'custom',
225
+ key: hookContext.key,
226
+ context: hookContext.context,
227
+ data: hookContext.data,
228
+ metricValue: hookContext.metricValue,
229
+ creationDate: Date.now(),
230
+ url: 'undefined' != typeof window ? window.location.href : void 0
231
+ };
232
+ if (!this.shouldProcessEvent()) return;
233
+ const processedEvent = this.processEvent(syntheticContext);
234
+ this.config.onNewEvent?.(processedEvent);
235
+ } catch (error) {
236
+ console.warn('Event processing error in AfterTrackHook:', error);
237
+ }
238
+ }
239
+ shouldProcessEvent() {
240
+ const filter = this.config.filter;
241
+ if (!filter) return true;
242
+ return !(filter.kinds && !filter.kinds.includes('custom')) && !(filter.categories && !filter.categories.includes('custom'));
243
+ }
244
+ processEvent(context) {
245
+ const timestamp = Date.now();
246
+ this.idCounter = (this.idCounter + 1) % 999999;
247
+ const randomPart = Math.random().toString(36).substring(2, 8);
248
+ const id = `${context.kind}-${timestamp}-${this.idCounter.toString().padStart(6, '0')}-${randomPart}`;
249
+ return {
250
+ id,
251
+ kind: context.kind,
252
+ key: context.key,
253
+ timestamp,
254
+ context,
255
+ displayName: `Custom: ${context.key || 'unknown'}`,
256
+ category: 'custom',
257
+ metadata: this.extractMetadata(context)
258
+ };
259
+ }
260
+ extractMetadata(context) {
261
+ return {
262
+ data: context.data,
263
+ metricValue: context.metricValue,
264
+ url: context.url
265
+ };
266
+ }
267
+ }
268
+ class AfterIdentifyHook {
269
+ config;
270
+ idCounter = 0;
271
+ constructor(config = {}){
272
+ this.config = {
273
+ filter: config.filter,
274
+ onNewEvent: config.onNewEvent
275
+ };
276
+ }
277
+ getMetadata() {
278
+ return {
279
+ name: 'AfterIdentifyHook'
280
+ };
281
+ }
282
+ afterIdentify(hookContext, data, result) {
283
+ try {
284
+ if ('completed' !== result.status) return data;
285
+ const syntheticContext = {
286
+ kind: 'identify',
287
+ context: hookContext.context,
288
+ creationDate: Date.now(),
289
+ contextKind: this.determineContextKind(hookContext.context)
290
+ };
291
+ if (!this.shouldProcessEvent()) return data;
292
+ const processedEvent = this.processEvent(syntheticContext);
293
+ this.config.onNewEvent?.(processedEvent);
294
+ } catch (error) {
295
+ console.warn('Event processing error in AfterIdentifyHook:', error);
296
+ }
297
+ return data;
298
+ }
299
+ determineContextKind(context) {
300
+ if (context && 'object' == typeof context) {
301
+ if ('kind' in context && context.kind) return context.kind;
302
+ if (context.anonymous) return 'anonymousUser';
303
+ }
304
+ return 'user';
305
+ }
306
+ shouldProcessEvent() {
307
+ const filter = this.config.filter;
308
+ if (!filter) return true;
309
+ return !(filter.kinds && !filter.kinds.includes('identify')) && !(filter.categories && !filter.categories.includes('identify'));
310
+ }
311
+ processEvent(context) {
312
+ const timestamp = Date.now();
313
+ this.idCounter = (this.idCounter + 1) % 999999;
314
+ const randomPart = Math.random().toString(36).substring(2, 8);
315
+ const id = `${context.kind}-${timestamp}-${this.idCounter.toString().padStart(6, '0')}-${randomPart}`;
316
+ return {
317
+ id,
318
+ kind: context.kind,
319
+ key: context.key,
320
+ timestamp,
321
+ context,
322
+ displayName: `Identify: ${context.context?.key || 'anonymous'}`,
323
+ category: 'identify',
324
+ metadata: this.extractMetadata(context)
325
+ };
326
+ }
327
+ extractMetadata(context) {
328
+ return {
329
+ contextKind: context.contextKind
330
+ };
331
+ }
332
+ }
333
+ class AfterEvaluationHook {
334
+ config;
335
+ idCounter = 0;
336
+ constructor(config = {}){
337
+ this.config = {
338
+ filter: config.filter,
339
+ onNewEvent: config.onNewEvent
340
+ };
341
+ }
342
+ getMetadata() {
343
+ return {
344
+ name: 'AfterEvaluationHook'
345
+ };
346
+ }
347
+ afterEvaluation(hookContext, data, detail) {
348
+ try {
349
+ const syntheticContext = {
350
+ kind: 'feature',
351
+ key: hookContext.flagKey,
352
+ context: hookContext.context,
353
+ value: detail.value,
354
+ variation: detail.variationIndex,
355
+ default: hookContext.defaultValue,
356
+ reason: detail.reason,
357
+ creationDate: Date.now()
358
+ };
359
+ if (!this.shouldProcessEvent(syntheticContext)) return data;
360
+ const processedEvent = this.processEvent(syntheticContext);
361
+ this.config.onNewEvent?.(processedEvent);
362
+ } catch (error) {
363
+ console.warn('Event processing error in AfterEvaluationHook:', error);
364
+ }
365
+ return data;
366
+ }
367
+ shouldProcessEvent(context) {
368
+ const filter = this.config.filter;
369
+ if (!filter) return true;
370
+ return !(filter.kinds && !filter.kinds.includes('feature')) && !(filter.categories && !filter.categories.includes('flag')) && !(filter.flagKeys && context.key && !filter.flagKeys.includes(context.key));
371
+ }
372
+ processEvent(context) {
373
+ const timestamp = Date.now();
374
+ this.idCounter = (this.idCounter + 1) % 999999;
375
+ const randomPart = Math.random().toString(36).substring(2, 8);
376
+ const id = `${context.kind}-${timestamp}-${this.idCounter.toString().padStart(6, '0')}-${randomPart}`;
377
+ return {
378
+ id,
379
+ kind: context.kind,
380
+ key: context.key,
381
+ timestamp,
382
+ context,
383
+ displayName: `Flag: ${context.key || 'unknown'}`,
384
+ category: 'flag',
385
+ metadata: this.extractMetadata(context)
386
+ };
387
+ }
388
+ extractMetadata(context) {
389
+ return {
390
+ flagVersion: context.version,
391
+ variation: context.variation,
392
+ trackEvents: context.trackEvents,
393
+ reason: context.reason,
394
+ defaultValue: context.default
395
+ };
396
+ }
397
+ }
398
+ const ANALYTICS_EVENT_PREFIX = 'ld.toolbar';
399
+ class EventInterceptionPlugin {
400
+ afterTrackHook;
401
+ afterIdentifyHook;
402
+ afterEvaluationHook;
403
+ eventStore;
404
+ config;
405
+ ldClient = null;
406
+ constructor(config = {}){
407
+ this.config = {
408
+ enableLogging: false,
409
+ eventCapacity: 100,
410
+ ...config
411
+ };
412
+ this.eventStore = new EventStore({
413
+ maxEvents: this.config.eventCapacity
414
+ });
415
+ const onNewEvent = (event)=>{
416
+ const isToolbarEvent = this.isToolbarEvent(event);
417
+ if (isToolbarEvent) return;
418
+ if (this.config.enableLogging) console.log('🎯 Event intercepted:', {
419
+ kind: event.kind,
420
+ key: event.key,
421
+ category: event.category,
422
+ displayName: event.displayName
423
+ });
424
+ this.eventStore.addEvent(event);
425
+ };
426
+ this.afterTrackHook = new AfterTrackHook({
427
+ filter: config.filter,
428
+ onNewEvent
429
+ });
430
+ this.afterIdentifyHook = new AfterIdentifyHook({
431
+ filter: config.filter,
432
+ onNewEvent
433
+ });
434
+ this.afterEvaluationHook = new AfterEvaluationHook({
435
+ filter: config.filter,
436
+ onNewEvent
437
+ });
438
+ }
439
+ isToolbarEvent(event) {
440
+ return event.key?.startsWith(ANALYTICS_EVENT_PREFIX) ?? false;
441
+ }
442
+ getMetadata() {
443
+ return {
444
+ name: 'EventInterceptionPlugin'
445
+ };
446
+ }
447
+ getHooks(_metadata) {
448
+ return [
449
+ this.afterTrackHook,
450
+ this.afterIdentifyHook,
451
+ this.afterEvaluationHook
452
+ ];
453
+ }
454
+ register(ldClient) {
455
+ this.ldClient = ldClient;
456
+ }
457
+ getClient() {
458
+ return this.ldClient;
459
+ }
460
+ getEvents() {
461
+ return this.eventStore.getEvents();
462
+ }
463
+ subscribe(listener) {
464
+ return this.eventStore.subscribe(listener);
465
+ }
466
+ clearEvents() {
467
+ this.eventStore.clear();
468
+ }
469
+ destroy() {
470
+ this.eventStore.destroy();
471
+ }
472
+ }
473
+ exports.EventInterceptionPlugin = __webpack_exports__.EventInterceptionPlugin;
474
+ exports.FlagOverridePlugin = __webpack_exports__.FlagOverridePlugin;
475
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
476
+ "EventInterceptionPlugin",
477
+ "FlagOverridePlugin"
478
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
479
+ Object.defineProperty(exports, '__esModule', {
480
+ value: true
481
+ });
482
+
483
+ //# sourceMappingURL=plugins.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugins.cjs","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../src/types/plugins/flagOverridePlugin.ts","../src/types/hooks/EventStore.ts","../src/types/hooks/AfterTrackHook.ts","../src/types/hooks/AfterIdentifyHook.ts","../src/types/hooks/AfterEvaluationHook.ts","../src/types/analytics.ts","../src/types/plugins/eventInterceptionPlugin.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type {\n LDClient,\n LDDebugOverride,\n LDPluginMetadata,\n LDFlagSet,\n Hook,\n LDPluginEnvironmentMetadata,\n} from 'launchdarkly-js-client-sdk';\nimport type { IFlagOverridePlugin } from './plugins';\n\n/**\n * Configuration options for the FlagOverridePlugin\n */\nexport type FlagOverridePluginConfig = {\n /** Namespace for localStorage keys. Defaults to 'ld-flag-override' */\n storageNamespace?: string;\n};\n\nconst DEFAULT_STORAGE_NAMESPACE = 'ld-flag-override';\n\nexport class FlagOverridePlugin implements IFlagOverridePlugin {\n private debugOverride?: LDDebugOverride;\n private config: Required<FlagOverridePluginConfig>;\n private ldClient: LDClient | null = null;\n\n constructor(config: FlagOverridePluginConfig = {}) {\n this.config = {\n storageNamespace: config.storageNamespace ?? DEFAULT_STORAGE_NAMESPACE,\n };\n }\n\n /**\n * Returns plugin metadata\n */\n getMetadata(): LDPluginMetadata {\n return {\n name: 'FlagOverridePlugin',\n };\n }\n\n /**\n * Returns the hooks for the plugin\n */\n getHooks(_metadata: LDPluginEnvironmentMetadata): Hook[] {\n return [];\n }\n\n /**\n * Called when the plugin is registered with the LaunchDarkly client\n */\n register(ldClient: LDClient): void {\n this.ldClient = ldClient;\n }\n\n /**\n * Called when the debug interface is available\n * Loads any existing overrides from localStorage\n */\n registerDebug(debugOverride: LDDebugOverride): void {\n this.debugOverride = debugOverride;\n this.loadExistingOverrides();\n }\n\n private loadExistingOverrides(): void {\n if (!this.debugOverride) return;\n\n const storage = this.getStorage();\n if (!storage) return;\n\n try {\n for (let i = 0; i < storage.length; i++) {\n const key = storage.key(i);\n if (!key?.startsWith(this.config.storageNamespace + ':')) continue;\n\n const storedValue = storage.getItem(key);\n if (storedValue) {\n try {\n const value = JSON.parse(storedValue);\n const flagKey = key.replace(this.config.storageNamespace + ':', '');\n\n this.debugOverride.setOverride(flagKey, value);\n } catch {\n console.warn('flagOverridePlugin: Invalid stored value for', key);\n storage.removeItem(key);\n }\n }\n }\n } catch (error) {\n console.error('flagOverridePlugin: Error loading existing overrides:', error);\n }\n }\n\n /**\n * Sets an override value for a feature flag and persists it to localStorage\n * @param flagKey - The key of the flag to override\n * @param value - The value to set for the flag\n */\n setOverride(flagKey: string, value: unknown): void {\n if (!this.debugOverride) {\n console.warn('flagOverridePlugin: Debug interface not available');\n return;\n }\n\n if (!flagKey || typeof flagKey !== 'string') {\n console.error('flagOverridePlugin: Invalid flag key:', flagKey);\n return;\n }\n\n if (value === undefined) {\n console.error('flagOverridePlugin: Cannot set undefined value for flag override');\n return;\n }\n\n try {\n this.persistOverride(flagKey, value);\n this.debugOverride.setOverride(flagKey, value);\n } catch (error) {\n console.error('flagOverridePlugin: Failed to set override:', error);\n }\n }\n\n /**\n * Removes an override for a specific feature flag\n * @param flagKey - The key of the flag to remove the override for\n */\n removeOverride(flagKey: string): void {\n if (!this.debugOverride) {\n console.warn('flagOverridePlugin: Debug interface not available');\n return;\n }\n\n if (!flagKey || typeof flagKey !== 'string') {\n console.error('flagOverridePlugin: Invalid flag key:', flagKey);\n return;\n }\n\n try {\n this.removePersistedOverride(flagKey);\n this.debugOverride.removeOverride(flagKey);\n } catch (error) {\n console.error('flagOverridePlugin: Failed to remove override:', error);\n }\n }\n\n /**\n * Clears all feature flag overrides from both memory and localStorage\n */\n clearAllOverrides(): void {\n if (!this.debugOverride) {\n console.warn('flagOverridePlugin: Debug interface not available');\n return;\n }\n\n try {\n this.clearPersistedOverrides();\n this.debugOverride.clearAllOverrides();\n } catch (error) {\n console.error('flagOverridePlugin: Failed to clear overrides:', error);\n }\n }\n\n /**\n * Returns all currently active feature flag overrides\n * @returns Record of flag keys to their override values\n */\n getAllOverrides(): LDFlagSet {\n if (!this.debugOverride) {\n console.warn('flagOverridePlugin: Debug interface not available');\n return {};\n }\n\n try {\n return this.debugOverride.getAllOverrides();\n } catch (error) {\n console.error('flagOverridePlugin: Failed to get overrides:', error);\n return {};\n }\n }\n\n /**\n * Returns the LaunchDarkly client instance\n * @returns The LaunchDarkly client\n */\n getClient(): LDClient | null {\n return this.ldClient;\n }\n\n private getStorage(): Storage | null {\n if (typeof window === 'undefined') return null;\n return window.localStorage;\n }\n\n private persistOverride(flagKey: string, value: unknown): void {\n const storage = this.getStorage();\n if (!storage) return;\n\n try {\n const storageKey = `${this.config.storageNamespace}:${flagKey}`;\n storage.setItem(storageKey, JSON.stringify(value));\n } catch (error) {\n console.error('flagOverridePlugin: Failed to persist override:', error);\n }\n }\n\n private removePersistedOverride(flagKey: string): void {\n const storage = this.getStorage();\n if (!storage) return;\n\n try {\n const storageKey = `${this.config.storageNamespace}:${flagKey}`;\n storage.removeItem(storageKey);\n } catch (error) {\n console.error('flagOverridePlugin: Failed to remove persisted override:', error);\n }\n }\n\n private clearPersistedOverrides(): void {\n const storage = this.getStorage();\n if (!storage) return;\n\n try {\n const keysToRemove: string[] = [];\n const prefix = this.config.storageNamespace + ':';\n\n for (let i = 0; i < storage.length; i++) {\n const key = storage.key(i);\n if (key?.startsWith(prefix)) {\n keysToRemove.push(key);\n }\n }\n\n keysToRemove.forEach((key) => storage.removeItem(key));\n } catch (error) {\n console.error('flagOverridePlugin: Failed to clear persisted overrides:', error);\n }\n }\n}\n","import type { ProcessedEvent } from '../events';\n\nconst DEFAULT_MAX_EVENTS = 100;\nexport interface EventStoreConfig {\n /** Maximum number of events to store */\n maxEvents?: number;\n}\n\nexport class EventStore {\n private events: ProcessedEvent[] = [];\n private listeners: Set<() => void> = new Set();\n private maxEvents: number;\n\n constructor(config: EventStoreConfig = {}) {\n this.maxEvents = config.maxEvents ?? DEFAULT_MAX_EVENTS;\n }\n\n addEvent(event: ProcessedEvent): void {\n try {\n this.events.push(event);\n if (this.events.length > this.maxEvents) {\n // Remove oldest events to maintain the limit\n this.events.splice(0, this.events.length - this.maxEvents);\n }\n this.notifyListeners();\n } catch (error) {\n console.warn('Event store error:', error);\n }\n }\n\n getEvents(): ProcessedEvent[] {\n return [...this.events];\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n listener(); // Send initial notification\n return () => this.listeners.delete(listener);\n }\n\n clear(): void {\n this.events = [];\n this.notifyListeners();\n }\n\n destroy(): void {\n this.listeners.clear();\n this.events = [];\n }\n\n private notifyListeners(): void {\n this.listeners.forEach((listener) => {\n try {\n listener();\n } catch (error) {\n console.warn('Listener error:', error);\n }\n });\n }\n}\n","import type { Hook } from 'launchdarkly-js-client-sdk';\nimport type { HookMetadata, TrackSeriesContext } from 'launchdarkly-js-sdk-common';\nimport type { EventFilter, ProcessedEvent, SyntheticEventContext } from '../events';\n\nexport type AfterTrackHookConfig = {\n onNewEvent?: (event: ProcessedEvent) => void;\n filter?: EventFilter;\n};\n\nexport class AfterTrackHook implements Hook {\n private config: AfterTrackHookConfig;\n private idCounter = 0;\n\n constructor(config: AfterTrackHookConfig = {}) {\n this.config = {\n filter: config.filter,\n onNewEvent: config.onNewEvent,\n };\n }\n\n getMetadata(): HookMetadata {\n return {\n name: 'AfterTrackHook',\n };\n }\n\n afterTrack(hookContext: TrackSeriesContext): void {\n try {\n const syntheticContext: SyntheticEventContext = {\n kind: 'custom',\n key: hookContext.key,\n context: hookContext.context,\n data: hookContext.data,\n metricValue: hookContext.metricValue,\n creationDate: Date.now(),\n url: typeof window !== 'undefined' ? window.location.href : undefined,\n };\n\n if (!this.shouldProcessEvent()) {\n return;\n }\n\n const processedEvent = this.processEvent(syntheticContext);\n\n this.config.onNewEvent?.(processedEvent);\n } catch (error) {\n // Simple error handling - just log and continue\n console.warn('Event processing error in AfterTrackHook:', error);\n }\n }\n\n private shouldProcessEvent(): boolean {\n const filter = this.config.filter;\n if (!filter) return true;\n\n // AfterTrackHook only handles custom events\n return (\n !(filter.kinds && !filter.kinds.includes('custom')) &&\n !(filter.categories && !filter.categories.includes('custom'))\n );\n }\n\n private processEvent(context: SyntheticEventContext): ProcessedEvent {\n const timestamp = Date.now();\n // Create a guaranteed unique ID using timestamp + counter + random\n this.idCounter = (this.idCounter + 1) % 999999; // Reset counter at 999999\n const randomPart = Math.random().toString(36).substring(2, 8);\n const id = `${context.kind}-${timestamp}-${this.idCounter.toString().padStart(6, '0')}-${randomPart}`;\n\n return {\n id,\n kind: context.kind,\n key: context.key,\n timestamp,\n context,\n displayName: `Custom: ${context.key || 'unknown'}`,\n category: 'custom',\n metadata: this.extractMetadata(context),\n };\n }\n\n private extractMetadata(context: SyntheticEventContext): Record<string, unknown> {\n // AfterTrackHook only handles custom events\n return {\n data: context.data,\n metricValue: context.metricValue,\n url: context.url,\n };\n }\n}\n","import type { Hook } from 'launchdarkly-js-client-sdk';\nimport type {\n HookMetadata,\n IdentifySeriesContext,\n IdentifySeriesData,\n IdentifySeriesResult,\n LDContext,\n} from 'launchdarkly-js-sdk-common';\nimport type { EventFilter, ProcessedEvent, SyntheticEventContext } from '../events';\n\nexport type AfterIdentifyHookConfig = {\n onNewEvent?: (event: ProcessedEvent) => void;\n filter?: EventFilter;\n};\n\nexport class AfterIdentifyHook implements Hook {\n private config: AfterIdentifyHookConfig;\n private idCounter = 0;\n\n constructor(config: AfterIdentifyHookConfig = {}) {\n this.config = {\n filter: config.filter,\n onNewEvent: config.onNewEvent,\n };\n }\n\n getMetadata(): HookMetadata {\n return {\n name: 'AfterIdentifyHook',\n };\n }\n\n afterIdentify(\n hookContext: IdentifySeriesContext,\n data: IdentifySeriesData,\n result: IdentifySeriesResult,\n ): IdentifySeriesData {\n try {\n // Only process successful identify operations\n if (result.status !== 'completed') {\n return data;\n }\n\n const syntheticContext: SyntheticEventContext = {\n kind: 'identify',\n context: hookContext.context,\n creationDate: Date.now(),\n contextKind: this.determineContextKind(hookContext.context),\n };\n\n if (!this.shouldProcessEvent()) {\n return data;\n }\n\n const processedEvent = this.processEvent(syntheticContext);\n\n this.config.onNewEvent?.(processedEvent);\n } catch (error) {\n // Simple error handling - just log and continue\n console.warn('Event processing error in AfterIdentifyHook:', error);\n }\n\n return data;\n }\n\n private determineContextKind(context: LDContext): string {\n if (context && typeof context === 'object') {\n if ('kind' in context && context.kind) {\n return context.kind;\n }\n // Legacy user context\n if (context.anonymous) {\n return 'anonymousUser';\n }\n return 'user';\n }\n return 'user';\n }\n\n private shouldProcessEvent(): boolean {\n const filter = this.config.filter;\n if (!filter) return true;\n\n // AfterIdentifyHook only handles identify events\n return (\n !(filter.kinds && !filter.kinds.includes('identify')) &&\n !(filter.categories && !filter.categories.includes('identify'))\n );\n }\n\n private processEvent(context: SyntheticEventContext): ProcessedEvent {\n const timestamp = Date.now();\n // Create a guaranteed unique ID using timestamp + counter + random\n this.idCounter = (this.idCounter + 1) % 999999; // Reset counter at 999999\n const randomPart = Math.random().toString(36).substring(2, 8);\n const id = `${context.kind}-${timestamp}-${this.idCounter.toString().padStart(6, '0')}-${randomPart}`;\n\n return {\n id,\n kind: context.kind,\n key: context.key,\n timestamp,\n context,\n displayName: `Identify: ${(context.context as any)?.key || 'anonymous'}`,\n category: 'identify',\n metadata: this.extractMetadata(context),\n };\n }\n\n private extractMetadata(context: SyntheticEventContext): Record<string, unknown> {\n // AfterIdentifyHook only handles identify events\n return {\n contextKind: context.contextKind,\n };\n }\n}\n","import type { Hook } from 'launchdarkly-js-client-sdk';\nimport type {\n HookMetadata,\n EvaluationSeriesData,\n LDEvaluationDetail,\n EvaluationSeriesContext,\n} from 'launchdarkly-js-sdk-common';\nimport type { EventFilter, ProcessedEvent, SyntheticEventContext } from '../events';\n\nexport type AfterEvaluationHookConfig = {\n onNewEvent?: (event: ProcessedEvent) => void;\n filter?: EventFilter;\n};\n\nexport class AfterEvaluationHook implements Hook {\n private config: AfterEvaluationHookConfig;\n private idCounter = 0;\n\n constructor(config: AfterEvaluationHookConfig = {}) {\n this.config = {\n filter: config.filter,\n onNewEvent: config.onNewEvent,\n };\n }\n\n getMetadata(): HookMetadata {\n return {\n name: 'AfterEvaluationHook',\n };\n }\n\n afterEvaluation(\n hookContext: EvaluationSeriesContext,\n data: EvaluationSeriesData,\n detail: LDEvaluationDetail,\n ): EvaluationSeriesData {\n try {\n const syntheticContext: SyntheticEventContext = {\n kind: 'feature',\n key: hookContext.flagKey,\n context: hookContext.context,\n value: detail.value,\n variation: detail.variationIndex,\n default: hookContext.defaultValue,\n reason: detail.reason,\n creationDate: Date.now(),\n // Note: We don't have access to version, trackEvents, or debugEventsUntilDate\n // from the afterEvaluation hook, so these will be undefined\n };\n\n if (!this.shouldProcessEvent(syntheticContext)) {\n return data;\n }\n\n const processedEvent = this.processEvent(syntheticContext);\n\n this.config.onNewEvent?.(processedEvent);\n } catch (error) {\n // Simple error handling - just log and continue\n console.warn('Event processing error in AfterEvaluationHook:', error);\n }\n\n return data;\n }\n\n private shouldProcessEvent(context: SyntheticEventContext): boolean {\n const filter = this.config.filter;\n if (!filter) return true;\n\n // AfterEvaluationHook only handles feature events\n return (\n !(filter.kinds && !filter.kinds.includes('feature')) &&\n !(filter.categories && !filter.categories.includes('flag')) &&\n !(filter.flagKeys && context.key && !filter.flagKeys.includes(context.key))\n );\n }\n\n private processEvent(context: SyntheticEventContext): ProcessedEvent {\n const timestamp = Date.now();\n // Create a guaranteed unique ID using timestamp + counter + random\n this.idCounter = (this.idCounter + 1) % 999999; // Reset counter at 999999\n const randomPart = Math.random().toString(36).substring(2, 8);\n const id = `${context.kind}-${timestamp}-${this.idCounter.toString().padStart(6, '0')}-${randomPart}`;\n\n return {\n id,\n kind: context.kind,\n key: context.key,\n timestamp,\n context,\n displayName: `Flag: ${context.key || 'unknown'}`,\n category: 'flag',\n metadata: this.extractMetadata(context),\n };\n }\n\n private extractMetadata(context: SyntheticEventContext): Record<string, unknown> {\n // AfterEvaluationHook only handles feature events\n return {\n flagVersion: context.version,\n variation: context.variation,\n trackEvents: context.trackEvents,\n reason: context.reason,\n defaultValue: context.default,\n };\n }\n}\n","export const ANALYTICS_EVENT_PREFIX = 'ld.toolbar';\n\nexport type FeedbackSentiment = 'positive' | 'negative';\n","import type { Hook, LDClient, LDPluginEnvironmentMetadata, LDPluginMetadata } from 'launchdarkly-js-client-sdk';\nimport { AfterTrackHook, AfterIdentifyHook, AfterEvaluationHook, EventStore } from '../hooks';\nimport type { EventFilter, ProcessedEvent } from '../events';\nimport type { IEventInterceptionPlugin } from './plugins';\nimport { ANALYTICS_EVENT_PREFIX } from '../analytics';\n\n/**\n * Configuration options for the EventInterceptionPlugin\n */\nexport interface EventInterceptionPluginConfig {\n /** Configuration for event filtering */\n filter?: EventFilter;\n /** Enable console logging for debugging */\n enableLogging?: boolean;\n /** Maximum number of events to store. The default value is 100. */\n eventCapacity?: number;\n}\n\n/**\n * Plugin dedicated to intercepting and processing LaunchDarkly events\n */\nexport class EventInterceptionPlugin implements IEventInterceptionPlugin {\n private afterTrackHook: AfterTrackHook;\n private afterIdentifyHook: AfterIdentifyHook;\n private afterEvaluationHook: AfterEvaluationHook;\n private eventStore: EventStore;\n private config: EventInterceptionPluginConfig;\n private ldClient: LDClient | null = null;\n\n constructor(config: EventInterceptionPluginConfig = {}) {\n this.config = {\n enableLogging: false,\n eventCapacity: 100,\n ...config,\n };\n\n this.eventStore = new EventStore({ maxEvents: this.config.eventCapacity });\n\n const onNewEvent = (event: ProcessedEvent) => {\n const isToolbarEvent = this.isToolbarEvent(event);\n if (isToolbarEvent) {\n return;\n }\n\n if (this.config.enableLogging) {\n console.log('🎯 Event intercepted:', {\n kind: event.kind,\n key: event.key,\n category: event.category,\n displayName: event.displayName,\n });\n }\n\n this.eventStore.addEvent(event);\n };\n\n this.afterTrackHook = new AfterTrackHook({\n filter: config.filter,\n onNewEvent,\n });\n\n this.afterIdentifyHook = new AfterIdentifyHook({\n filter: config.filter,\n onNewEvent,\n });\n\n this.afterEvaluationHook = new AfterEvaluationHook({\n filter: config.filter,\n onNewEvent,\n });\n }\n\n isToolbarEvent(event: ProcessedEvent): boolean {\n return event.key?.startsWith(ANALYTICS_EVENT_PREFIX) ?? false;\n }\n\n getMetadata(): LDPluginMetadata {\n return {\n name: 'EventInterceptionPlugin',\n };\n }\n\n getHooks(_metadata: LDPluginEnvironmentMetadata): Hook[] {\n return [this.afterTrackHook, this.afterIdentifyHook, this.afterEvaluationHook];\n }\n\n register(ldClient: LDClient): void {\n this.ldClient = ldClient;\n }\n\n getClient(): LDClient | null {\n return this.ldClient;\n }\n\n getEvents(): ProcessedEvent[] {\n return this.eventStore.getEvents();\n }\n\n subscribe(listener: () => void): () => void {\n return this.eventStore.subscribe(listener);\n }\n\n clearEvents(): void {\n this.eventStore.clear();\n }\n\n destroy(): void {\n this.eventStore.destroy();\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","DEFAULT_STORAGE_NAMESPACE","FlagOverridePlugin","config","_metadata","ldClient","debugOverride","storage","i","storedValue","value","JSON","flagKey","console","error","undefined","window","storageKey","keysToRemove","prefix","DEFAULT_MAX_EVENTS","EventStore","Set","event","listener","AfterTrackHook","hookContext","syntheticContext","Date","processedEvent","filter","context","timestamp","randomPart","Math","id","AfterIdentifyHook","data","result","AfterEvaluationHook","detail","ANALYTICS_EVENT_PREFIX","EventInterceptionPlugin","onNewEvent","isToolbarEvent"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Plugin exports for the LaunchDarkly Toolbar
3
+ *
4
+ * This entry point allows importing plugins separately from the main toolbar
5
+ * for better bundle size optimization when using lazy loading.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { FlagOverridePlugin, EventInterceptionPlugin } from '@launchdarkly/toolbar/plugins';
10
+ *
11
+ * const flagOverridePlugin = new FlagOverridePlugin({
12
+ * storageNamespace: 'my-app-overrides',
13
+ * });
14
+ *
15
+ * const eventInterceptionPlugin = new EventInterceptionPlugin({
16
+ * eventCapacity: 150,
17
+ * });
18
+ * ```
19
+ */
20
+ export { FlagOverridePlugin, EventInterceptionPlugin } from './types/plugins';
21
+ export type { FlagOverridePluginConfig, EventInterceptionPluginConfig, IFlagOverridePlugin, IEventInterceptionPlugin, } from './types/plugins';