@launchdarkly/toolbar 0.12.0-beta.1 → 0.13.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/README.md +17 -13
  2. package/dist/hooks/AfterEvaluationHook.d.ts +17 -0
  3. package/dist/hooks/AfterIdentifyHook.d.ts +18 -0
  4. package/dist/hooks/AfterTrackHook.d.ts +17 -0
  5. package/dist/hooks/EventStore.d.ts +11 -0
  6. package/dist/hooks/index.d.ts +7 -0
  7. package/dist/index.d.ts +6 -1
  8. package/dist/js/index.js +1822 -813
  9. package/dist/js/plugins/FlagOverridePlugin.js +3 -0
  10. package/dist/js/plugins/index.js +296 -1
  11. package/dist/plugins/EventInterceptionPlugin.d.ts +30 -0
  12. package/dist/plugins/FlagOverridePlugin.d.ts +8 -3
  13. package/dist/plugins/index.d.ts +2 -0
  14. package/dist/tests/hooks/AfterEvaluationHook.test.d.ts +1 -0
  15. package/dist/tests/hooks/AfterIdentifyHook.test.d.ts +1 -0
  16. package/dist/tests/hooks/AfterTrackHook.test.d.ts +1 -0
  17. package/dist/tests/hooks/EventStore.test.d.ts +1 -0
  18. package/dist/types/events.d.ts +64 -0
  19. package/dist/types/plugin.d.ts +21 -0
  20. package/dist/ui/Toolbar/LaunchDarklyToolbar.d.ts +4 -2
  21. package/dist/ui/Toolbar/TabContent/EventsTabContent.css.d.ts +18 -0
  22. package/dist/ui/Toolbar/TabContent/EventsTabContent.d.ts +6 -1
  23. package/dist/ui/Toolbar/components/DoNotTrackWarning.css.d.ts +5 -0
  24. package/dist/ui/Toolbar/components/DoNotTrackWarning.d.ts +1 -0
  25. package/dist/ui/Toolbar/components/ExpandedToolbarContent.d.ts +3 -2
  26. package/dist/ui/Toolbar/components/TabContentRenderer.d.ts +3 -2
  27. package/dist/ui/Toolbar/components/index.d.ts +1 -0
  28. package/dist/ui/Toolbar/constants/animations.d.ts +27 -0
  29. package/dist/ui/Toolbar/hooks/index.d.ts +2 -0
  30. package/dist/ui/Toolbar/hooks/useCurrentDate.d.ts +5 -0
  31. package/dist/ui/Toolbar/hooks/useEvents.d.ts +13 -0
  32. package/dist/ui/Toolbar/types/toolbar.d.ts +3 -3
  33. package/dist/utils/browser.d.ts +7 -0
  34. package/dist/utils/index.d.ts +1 -0
  35. package/package.json +2 -3
@@ -13,6 +13,9 @@ class FlagOverridePlugin {
13
13
  name: 'FlagOverridePlugin'
14
14
  };
15
15
  }
16
+ getHooks(_metadata) {
17
+ return [];
18
+ }
16
19
  register(ldClient) {
17
20
  this.ldClient = ldClient;
18
21
  }
@@ -13,6 +13,9 @@ class FlagOverridePlugin {
13
13
  name: 'FlagOverridePlugin'
14
14
  };
15
15
  }
16
+ getHooks(_metadata) {
17
+ return [];
18
+ }
16
19
  register(ldClient) {
17
20
  this.ldClient = ldClient;
18
21
  }
@@ -127,4 +130,296 @@ class FlagOverridePlugin {
127
130
  }
128
131
  }
129
132
  }
130
- export { FlagOverridePlugin };
133
+ const MAX_EVENTS = 100;
134
+ class EventStore {
135
+ events = [];
136
+ listeners = new Set();
137
+ addEvent(event) {
138
+ try {
139
+ this.events.push(event);
140
+ if (this.events.length > MAX_EVENTS) this.events.splice(0, this.events.length - MAX_EVENTS);
141
+ this.notifyListeners();
142
+ } catch (error) {
143
+ console.warn('Event store error:', error);
144
+ }
145
+ }
146
+ getEvents() {
147
+ return [
148
+ ...this.events
149
+ ];
150
+ }
151
+ subscribe(listener) {
152
+ this.listeners.add(listener);
153
+ listener();
154
+ return ()=>this.listeners.delete(listener);
155
+ }
156
+ clear() {
157
+ this.events = [];
158
+ this.notifyListeners();
159
+ }
160
+ destroy() {
161
+ this.listeners.clear();
162
+ this.events = [];
163
+ }
164
+ notifyListeners() {
165
+ this.listeners.forEach((listener)=>{
166
+ try {
167
+ listener();
168
+ } catch (error) {
169
+ console.warn('Listener error:', error);
170
+ }
171
+ });
172
+ }
173
+ }
174
+ class AfterTrackHook {
175
+ config;
176
+ idCounter = 0;
177
+ constructor(config = {}){
178
+ this.config = {
179
+ filter: config.filter,
180
+ onNewEvent: config.onNewEvent
181
+ };
182
+ }
183
+ getMetadata() {
184
+ return {
185
+ name: 'AfterTrackHook'
186
+ };
187
+ }
188
+ afterTrack(hookContext) {
189
+ try {
190
+ const syntheticContext = {
191
+ kind: 'custom',
192
+ key: hookContext.key,
193
+ context: hookContext.context,
194
+ data: hookContext.data,
195
+ metricValue: hookContext.metricValue,
196
+ creationDate: Date.now(),
197
+ url: 'undefined' != typeof window ? window.location.href : void 0
198
+ };
199
+ if (!this.shouldProcessEvent()) return;
200
+ const processedEvent = this.processEvent(syntheticContext);
201
+ this.config.onNewEvent?.(processedEvent);
202
+ } catch (error) {
203
+ console.warn('Event processing error in AfterTrackHook:', error);
204
+ }
205
+ }
206
+ shouldProcessEvent() {
207
+ const filter = this.config.filter;
208
+ if (!filter) return true;
209
+ return !(filter.kinds && !filter.kinds.includes('custom')) && !(filter.categories && !filter.categories.includes('custom'));
210
+ }
211
+ processEvent(context) {
212
+ const timestamp = Date.now();
213
+ this.idCounter = (this.idCounter + 1) % 999999;
214
+ const randomPart = Math.random().toString(36).substring(2, 8);
215
+ const id = `${context.kind}-${timestamp}-${this.idCounter.toString().padStart(6, '0')}-${randomPart}`;
216
+ return {
217
+ id,
218
+ kind: context.kind,
219
+ key: context.key,
220
+ timestamp,
221
+ context,
222
+ displayName: `Custom: ${context.key || 'unknown'}`,
223
+ category: 'custom',
224
+ metadata: this.extractMetadata(context)
225
+ };
226
+ }
227
+ extractMetadata(context) {
228
+ return {
229
+ data: context.data,
230
+ metricValue: context.metricValue,
231
+ url: context.url
232
+ };
233
+ }
234
+ }
235
+ class AfterIdentifyHook {
236
+ config;
237
+ idCounter = 0;
238
+ constructor(config = {}){
239
+ this.config = {
240
+ filter: config.filter,
241
+ onNewEvent: config.onNewEvent
242
+ };
243
+ }
244
+ getMetadata() {
245
+ return {
246
+ name: 'AfterIdentifyHook'
247
+ };
248
+ }
249
+ afterIdentify(hookContext, data, result) {
250
+ try {
251
+ if ('completed' !== result.status) return data;
252
+ const syntheticContext = {
253
+ kind: 'identify',
254
+ context: hookContext.context,
255
+ creationDate: Date.now(),
256
+ contextKind: this.determineContextKind(hookContext.context)
257
+ };
258
+ if (!this.shouldProcessEvent()) return data;
259
+ const processedEvent = this.processEvent(syntheticContext);
260
+ this.config.onNewEvent?.(processedEvent);
261
+ } catch (error) {
262
+ console.warn('Event processing error in AfterIdentifyHook:', error);
263
+ }
264
+ return data;
265
+ }
266
+ determineContextKind(context) {
267
+ if (context && 'object' == typeof context) {
268
+ if ('kind' in context && context.kind) return context.kind;
269
+ if (context.anonymous) return 'anonymousUser';
270
+ }
271
+ return 'user';
272
+ }
273
+ shouldProcessEvent() {
274
+ const filter = this.config.filter;
275
+ if (!filter) return true;
276
+ return !(filter.kinds && !filter.kinds.includes('identify')) && !(filter.categories && !filter.categories.includes('identify'));
277
+ }
278
+ processEvent(context) {
279
+ const timestamp = Date.now();
280
+ this.idCounter = (this.idCounter + 1) % 999999;
281
+ const randomPart = Math.random().toString(36).substring(2, 8);
282
+ const id = `${context.kind}-${timestamp}-${this.idCounter.toString().padStart(6, '0')}-${randomPart}`;
283
+ return {
284
+ id,
285
+ kind: context.kind,
286
+ key: context.key,
287
+ timestamp,
288
+ context,
289
+ displayName: `Identify: ${context.context?.key || 'anonymous'}`,
290
+ category: 'identify',
291
+ metadata: this.extractMetadata(context)
292
+ };
293
+ }
294
+ extractMetadata(context) {
295
+ return {
296
+ contextKind: context.contextKind
297
+ };
298
+ }
299
+ }
300
+ class AfterEvaluationHook {
301
+ config;
302
+ idCounter = 0;
303
+ constructor(config = {}){
304
+ this.config = {
305
+ filter: config.filter,
306
+ onNewEvent: config.onNewEvent
307
+ };
308
+ }
309
+ getMetadata() {
310
+ return {
311
+ name: 'AfterEvaluationHook'
312
+ };
313
+ }
314
+ afterEvaluation(hookContext, data, detail) {
315
+ try {
316
+ const syntheticContext = {
317
+ kind: 'feature',
318
+ key: hookContext.flagKey,
319
+ context: hookContext.context,
320
+ value: detail.value,
321
+ variation: detail.variationIndex,
322
+ default: hookContext.defaultValue,
323
+ reason: detail.reason,
324
+ creationDate: Date.now()
325
+ };
326
+ if (!this.shouldProcessEvent(syntheticContext)) return data;
327
+ const processedEvent = this.processEvent(syntheticContext);
328
+ this.config.onNewEvent?.(processedEvent);
329
+ } catch (error) {
330
+ console.warn('Event processing error in AfterEvaluationHook:', error);
331
+ }
332
+ return data;
333
+ }
334
+ shouldProcessEvent(context) {
335
+ const filter = this.config.filter;
336
+ if (!filter) return true;
337
+ return !(filter.kinds && !filter.kinds.includes('feature')) && !(filter.categories && !filter.categories.includes('flag')) && !(filter.flagKeys && context.key && !filter.flagKeys.includes(context.key));
338
+ }
339
+ processEvent(context) {
340
+ const timestamp = Date.now();
341
+ this.idCounter = (this.idCounter + 1) % 999999;
342
+ const randomPart = Math.random().toString(36).substring(2, 8);
343
+ const id = `${context.kind}-${timestamp}-${this.idCounter.toString().padStart(6, '0')}-${randomPart}`;
344
+ return {
345
+ id,
346
+ kind: context.kind,
347
+ key: context.key,
348
+ timestamp,
349
+ context,
350
+ displayName: `Flag: ${context.key || 'unknown'}`,
351
+ category: 'flag',
352
+ metadata: this.extractMetadata(context)
353
+ };
354
+ }
355
+ extractMetadata(context) {
356
+ return {
357
+ flagVersion: context.version,
358
+ variation: context.variation,
359
+ trackEvents: context.trackEvents,
360
+ reason: context.reason,
361
+ defaultValue: context.default
362
+ };
363
+ }
364
+ }
365
+ class EventInterceptionPlugin {
366
+ afterTrackHook;
367
+ afterIdentifyHook;
368
+ afterEvaluationHook;
369
+ eventStore;
370
+ config;
371
+ constructor(config = {}){
372
+ this.config = {
373
+ enableLogging: true,
374
+ ...config
375
+ };
376
+ this.eventStore = new EventStore();
377
+ const onNewEvent = (event)=>{
378
+ if (this.config.enableLogging) console.log('🎯 Event intercepted:', {
379
+ kind: event.kind,
380
+ key: event.key,
381
+ category: event.category,
382
+ displayName: event.displayName
383
+ });
384
+ this.eventStore.addEvent(event);
385
+ };
386
+ this.afterTrackHook = new AfterTrackHook({
387
+ filter: config.filter,
388
+ onNewEvent
389
+ });
390
+ this.afterIdentifyHook = new AfterIdentifyHook({
391
+ filter: config.filter,
392
+ onNewEvent
393
+ });
394
+ this.afterEvaluationHook = new AfterEvaluationHook({
395
+ filter: config.filter,
396
+ onNewEvent
397
+ });
398
+ }
399
+ getMetadata() {
400
+ return {
401
+ name: 'EventInterceptionPlugin'
402
+ };
403
+ }
404
+ getHooks(_metadata) {
405
+ return [
406
+ this.afterTrackHook,
407
+ this.afterIdentifyHook,
408
+ this.afterEvaluationHook
409
+ ];
410
+ }
411
+ register(_client) {}
412
+ getEvents() {
413
+ return this.eventStore.getEvents();
414
+ }
415
+ subscribe(listener) {
416
+ return this.eventStore.subscribe(listener);
417
+ }
418
+ clearEvents() {
419
+ this.eventStore.clear();
420
+ }
421
+ destroy() {
422
+ this.eventStore.destroy();
423
+ }
424
+ }
425
+ export { EventInterceptionPlugin, FlagOverridePlugin };
@@ -0,0 +1,30 @@
1
+ import type { Hook, LDClient, LDPluginEnvironmentMetadata, LDPluginMetadata } from 'launchdarkly-js-client-sdk';
2
+ import type { EventFilter, ProcessedEvent } from '../types/events';
3
+ import type { IEventInterceptionPlugin } from '../types/plugin';
4
+ /**
5
+ * Configuration options for the EventInterceptionPlugin
6
+ */
7
+ export interface EventInterceptionPluginConfig {
8
+ /** Configuration for event filtering */
9
+ filter?: EventFilter;
10
+ /** Enable console logging for debugging */
11
+ enableLogging?: boolean;
12
+ }
13
+ /**
14
+ * Plugin dedicated to intercepting and processing LaunchDarkly events
15
+ */
16
+ export declare class EventInterceptionPlugin implements IEventInterceptionPlugin {
17
+ private afterTrackHook;
18
+ private afterIdentifyHook;
19
+ private afterEvaluationHook;
20
+ private eventStore;
21
+ private config;
22
+ constructor(config?: EventInterceptionPluginConfig);
23
+ getMetadata(): LDPluginMetadata;
24
+ getHooks(_metadata: LDPluginEnvironmentMetadata): Hook[];
25
+ register(_client: LDClient): void;
26
+ getEvents(): ProcessedEvent[];
27
+ subscribe(listener: () => void): () => void;
28
+ clearEvents(): void;
29
+ destroy(): void;
30
+ }
@@ -1,4 +1,5 @@
1
- import type { LDClient, LDPlugin, LDDebugOverride, LDPluginMetadata } from 'launchdarkly-js-client-sdk';
1
+ import type { LDClient, LDDebugOverride, LDPluginMetadata, LDFlagSet, Hook, LDPluginEnvironmentMetadata } from 'launchdarkly-js-client-sdk';
2
+ import type { IFlagOverridePlugin } from '../types/plugin';
2
3
  /**
3
4
  * Configuration options for the FlagOverridePlugin
4
5
  */
@@ -6,7 +7,7 @@ export type FlagOverridePluginConfig = {
6
7
  /** Namespace for localStorage keys. Defaults to 'ld-flag-override' */
7
8
  storageNamespace?: string;
8
9
  };
9
- export declare class FlagOverridePlugin implements LDPlugin {
10
+ export declare class FlagOverridePlugin implements IFlagOverridePlugin {
10
11
  private debugOverride?;
11
12
  private config;
12
13
  private ldClient;
@@ -15,6 +16,10 @@ export declare class FlagOverridePlugin implements LDPlugin {
15
16
  * Returns plugin metadata
16
17
  */
17
18
  getMetadata(): LDPluginMetadata;
19
+ /**
20
+ * Returns the hooks for the plugin
21
+ */
22
+ getHooks(_metadata: LDPluginEnvironmentMetadata): Hook[];
18
23
  /**
19
24
  * Called when the plugin is registered with the LaunchDarkly client
20
25
  */
@@ -44,7 +49,7 @@ export declare class FlagOverridePlugin implements LDPlugin {
44
49
  * Returns all currently active feature flag overrides
45
50
  * @returns Record of flag keys to their override values
46
51
  */
47
- getAllOverrides(): Record<string, unknown>;
52
+ getAllOverrides(): LDFlagSet;
48
53
  /**
49
54
  * Returns the LaunchDarkly client instance
50
55
  * @returns The LaunchDarkly client
@@ -1,2 +1,4 @@
1
1
  export { FlagOverridePlugin } from './FlagOverridePlugin';
2
2
  export type { FlagOverridePluginConfig } from './FlagOverridePlugin';
3
+ export { EventInterceptionPlugin } from './EventInterceptionPlugin';
4
+ export type { EventInterceptionPluginConfig } from './EventInterceptionPlugin';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,64 @@
1
+ export interface SyntheticEventContext {
2
+ readonly kind: EventKind;
3
+ readonly key?: string;
4
+ readonly context?: object;
5
+ readonly creationDate: number;
6
+ readonly data?: unknown;
7
+ readonly metricValue?: number;
8
+ readonly url?: string;
9
+ readonly value?: any;
10
+ readonly variation?: number | null;
11
+ readonly default?: any;
12
+ readonly reason?: object;
13
+ readonly version?: number;
14
+ readonly trackEvents?: boolean;
15
+ readonly debugEventsUntilDate?: number;
16
+ readonly contextKind?: string;
17
+ }
18
+ /**
19
+ * Valid event kinds that can be emitted by the LaunchDarkly SDK
20
+ */
21
+ declare const VALID_EVENT_KINDS: readonly ["identify", "feature", "custom", "debug", "summary", "diagnostic"];
22
+ /**
23
+ * Valid event categories used for organizing events
24
+ */
25
+ declare const VALID_EVENT_CATEGORIES: readonly ["flag", "custom", "identify", "debug"];
26
+ /**
27
+ * Strict typing for event kinds based on LaunchDarkly's event system
28
+ */
29
+ export type EventKind = (typeof VALID_EVENT_KINDS)[number];
30
+ /**
31
+ * Event categories for UI organization
32
+ */
33
+ export type EventCategory = (typeof VALID_EVENT_CATEGORIES)[number];
34
+ /**
35
+ * Enhanced processed event
36
+ */
37
+ export interface ProcessedEvent {
38
+ readonly id: string;
39
+ readonly kind: EventKind;
40
+ readonly key?: string;
41
+ readonly timestamp: number;
42
+ readonly context: SyntheticEventContext;
43
+ readonly displayName: string;
44
+ readonly category: EventCategory;
45
+ readonly metadata?: Readonly<Record<string, unknown>>;
46
+ }
47
+ /**
48
+ * Event filter configuration
49
+ */
50
+ export interface EventFilter {
51
+ readonly kinds?: ReadonlyArray<EventKind>;
52
+ readonly categories?: ReadonlyArray<EventCategory>;
53
+ readonly flagKeys?: ReadonlyArray<string>;
54
+ readonly timeRange?: {
55
+ readonly start: number;
56
+ readonly end: number;
57
+ };
58
+ }
59
+ /**
60
+ * Type guards for event validation
61
+ */
62
+ export declare function isValidEventKind(kind: string): kind is EventKind;
63
+ export declare function isValidEventCategory(category: string): category is EventCategory;
64
+ export {};
@@ -1,4 +1,5 @@
1
1
  import type { LDClient, LDDebugOverride, LDFlagSet, LDFlagValue, LDPlugin } from 'launchdarkly-js-client-sdk';
2
+ import type { ProcessedEvent } from './events';
2
3
  /**
3
4
  * Interface for flag override plugins that can be used with the LaunchDarkly Toolbar
4
5
  */
@@ -29,3 +30,23 @@ export interface IFlagOverridePlugin extends LDPlugin, LDDebugOverride {
29
30
  */
30
31
  getClient(): LDClient | null;
31
32
  }
33
+ /**
34
+ * Interface for event interception plugins that can be used with the LaunchDarkly Toolbar
35
+ */
36
+ export interface IEventInterceptionPlugin extends LDPlugin {
37
+ /**
38
+ * Gets all intercepted events from the event store
39
+ * @returns Array of processed events
40
+ */
41
+ getEvents(): ProcessedEvent[];
42
+ /**
43
+ * Subscribes to event store changes
44
+ * @param listener - Callback function to be called when events change
45
+ * @returns Unsubscribe function
46
+ */
47
+ subscribe(listener: () => void): () => void;
48
+ /**
49
+ * Clears all events from the event store
50
+ */
51
+ clearEvents(): void;
52
+ }
@@ -1,14 +1,16 @@
1
1
  import { ToolbarMode, ToolbarPosition } from './types/toolbar';
2
- import type { IFlagOverridePlugin } from '../../types/plugin';
2
+ import type { IEventInterceptionPlugin, IFlagOverridePlugin } from '../../types/plugin';
3
3
  export interface LdToolbarProps {
4
- flagOverridePlugin?: IFlagOverridePlugin;
5
4
  mode: ToolbarMode;
5
+ flagOverridePlugin?: IFlagOverridePlugin;
6
+ eventInterceptionPlugin?: IEventInterceptionPlugin;
6
7
  }
7
8
  export declare function LdToolbar(props: LdToolbarProps): import("react/jsx-runtime").JSX.Element;
8
9
  export interface LaunchDarklyToolbarProps {
9
10
  devServerUrl?: string;
10
11
  projectKey?: string;
11
12
  flagOverridePlugin?: IFlagOverridePlugin;
13
+ eventInterceptionPlugin?: IEventInterceptionPlugin;
12
14
  pollIntervalInMs?: number;
13
15
  position?: ToolbarPosition;
14
16
  }
@@ -1,3 +1,21 @@
1
+ export declare const statsHeader: string;
2
+ export declare const statsText: string;
1
3
  export declare const eventInfo: string;
2
4
  export declare const eventName: string;
3
5
  export declare const eventMeta: string;
6
+ export declare const eventBadge: string;
7
+ export declare const eventBadgeFeature: string;
8
+ export declare const eventBadgeIdentify: string;
9
+ export declare const eventBadgeCustom: string;
10
+ export declare const eventBadgeDebug: string;
11
+ export declare const eventBadgeSummary: string;
12
+ export declare const eventBadgeDiagnostic: string;
13
+ export declare const eventBadgeDefault: string;
14
+ export declare const virtualContainer: string;
15
+ export declare const virtualInner: string;
16
+ export declare const virtualItem: string;
17
+ export declare const liveTailContainer: string;
18
+ export declare const liveTailIndicator: string;
19
+ export declare const liveTailDot: string;
20
+ export declare const liveTailText: string;
21
+ export declare const liveTailSubtext: string;
@@ -1 +1,6 @@
1
- export declare function EventsTabContent(): import("react/jsx-runtime").JSX.Element;
1
+ import type { IEventInterceptionPlugin } from '../../../types/plugin';
2
+ interface EventsTabContentProps {
3
+ eventInterceptionPlugin?: IEventInterceptionPlugin;
4
+ }
5
+ export declare function EventsTabContent(props: EventsTabContentProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,5 @@
1
+ export declare const warningContainer: string;
2
+ export declare const warningMessage: string;
3
+ export declare const warningTitle: string;
4
+ export declare const warningText: string;
5
+ export declare const warningHelp: string;
@@ -0,0 +1 @@
1
+ export declare function DoNotTrackWarning(): import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import { Dispatch, SetStateAction } from 'react';
2
2
  import { ActiveTabId, ToolbarMode } from '../types';
3
- import type { IFlagOverridePlugin } from '../../../types/plugin';
3
+ import type { IFlagOverridePlugin, IEventInterceptionPlugin } from '../../../types/plugin';
4
4
  interface ExpandedToolbarContentProps {
5
5
  isExpanded: boolean;
6
6
  activeTab: ActiveTabId;
@@ -11,8 +11,9 @@ interface ExpandedToolbarContentProps {
11
11
  onClose: () => void;
12
12
  onTabChange: (tabId: string) => void;
13
13
  setSearchIsExpanded: Dispatch<SetStateAction<boolean>>;
14
- flagOverridePlugin?: IFlagOverridePlugin;
15
14
  mode: ToolbarMode;
15
+ flagOverridePlugin?: IFlagOverridePlugin;
16
+ eventInterceptionPlugin?: IEventInterceptionPlugin;
16
17
  }
17
18
  export declare function ExpandedToolbarContent(props: ExpandedToolbarContentProps): import("react/jsx-runtime").JSX.Element;
18
19
  export {};
@@ -1,10 +1,11 @@
1
1
  import { TabId, ToolbarMode } from '../types';
2
- import type { IFlagOverridePlugin } from '../../../types/plugin';
2
+ import type { IFlagOverridePlugin, IEventInterceptionPlugin } from '../../../types/plugin';
3
3
  interface TabContentRendererProps {
4
4
  activeTab: TabId;
5
5
  slideDirection: number;
6
- flagOverridePlugin?: IFlagOverridePlugin;
7
6
  mode: ToolbarMode;
7
+ flagOverridePlugin?: IFlagOverridePlugin;
8
+ eventInterceptionPlugin?: IEventInterceptionPlugin;
8
9
  }
9
10
  export declare function TabContentRenderer(props: TabContentRendererProps): import("react/jsx-runtime").JSX.Element | null;
10
11
  export {};
@@ -1,6 +1,7 @@
1
1
  export { ActionButtonsContainer } from './ActionButtonsContainer';
2
2
  export { CircleLogo } from './CircleLogo';
3
3
  export { ConnectionStatus } from './ConnectionStatus';
4
+ export { DoNotTrackWarning } from './DoNotTrackWarning';
4
5
  export { ExpandedToolbarContent } from './ExpandedToolbarContent';
5
6
  export { LaunchDarklyIcon } from './icons/LaunchDarklyIcon';
6
7
  export { StatusDot } from './StatusDot';
@@ -75,6 +75,33 @@ export declare const ANIMATION_CONFIG: {
75
75
  };
76
76
  readonly delay: 0.3;
77
77
  };
78
+ readonly eventList: {
79
+ readonly liveTail: {
80
+ readonly dot: {
81
+ readonly scale: number[];
82
+ readonly opacity: number[];
83
+ readonly transition: {
84
+ readonly duration: 1.5;
85
+ readonly repeat: number;
86
+ readonly ease: "easeInOut";
87
+ };
88
+ };
89
+ readonly container: {
90
+ readonly initial: {
91
+ readonly opacity: 0;
92
+ readonly y: 20;
93
+ };
94
+ readonly animate: {
95
+ readonly opacity: 1;
96
+ readonly y: 0;
97
+ };
98
+ readonly transition: {
99
+ readonly duration: 0.4;
100
+ readonly ease: readonly [0.25, 0.46, 0.45, 0.94];
101
+ };
102
+ };
103
+ };
104
+ };
78
105
  };
79
106
  export declare const DIMENSIONS: {
80
107
  readonly collapsed: {
@@ -3,3 +3,5 @@ export { useToolbarAnimations } from './useToolbarAnimations';
3
3
  export { useToolbarVisibility } from './useToolbarVisibility';
4
4
  export { useToolbarDrag } from './useToolbarDrag';
5
5
  export { useKeyPressed } from './useKeyPressed';
6
+ export { useEvents } from './useEvents';
7
+ export { useCurrentDate } from './useCurrentDate';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Hook that provides the current date and updates it at a specified interval
3
+ * Useful for displaying relative timestamps that update in real-time
4
+ */
5
+ export declare function useCurrentDate(updateInterval?: number): Date;
@@ -0,0 +1,13 @@
1
+ import type { ProcessedEvent } from '../../../types/events';
2
+ import { IEventInterceptionPlugin } from '../../../types/plugin';
3
+ interface EventStats {
4
+ totalEvents: number;
5
+ eventsByKind: Record<string, number>;
6
+ eventsByFlag: Record<string, number>;
7
+ }
8
+ interface UseEventsReturn {
9
+ events: ProcessedEvent[];
10
+ eventStats: EventStats;
11
+ }
12
+ export declare function useEvents(eventInterceptionPlugin: IEventInterceptionPlugin | undefined, searchTerm?: string): UseEventsReturn;
13
+ export {};