@anymux/ui-kit 0.1.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 (244) hide show
  1. package/dist/ExplorerLayout-CSIJd7N4.js +105 -0
  2. package/dist/ExplorerLayout-CSIJd7N4.js.map +1 -0
  3. package/dist/FileBrowserContext-B6jixa2j.js +11 -0
  4. package/dist/FileBrowserContext-B6jixa2j.js.map +1 -0
  5. package/dist/calendar-DSlrbHoj.js +761 -0
  6. package/dist/calendar-DSlrbHoj.js.map +1 -0
  7. package/dist/calendar.d.ts +3 -0
  8. package/dist/calendar.js +3 -0
  9. package/dist/contacts-DQXTZzHc.js +539 -0
  10. package/dist/contacts-DQXTZzHc.js.map +1 -0
  11. package/dist/contacts.d.ts +3 -0
  12. package/dist/contacts.js +3 -0
  13. package/dist/file-browser-m5atC3kF.js +6755 -0
  14. package/dist/file-browser-m5atC3kF.js.map +1 -0
  15. package/dist/file-browser.d.ts +11 -0
  16. package/dist/file-browser.js +9 -0
  17. package/dist/git-B55e6LL-.js +561 -0
  18. package/dist/git-B55e6LL-.js.map +1 -0
  19. package/dist/git.d.ts +2 -0
  20. package/dist/git.js +3 -0
  21. package/dist/iconMap-V4B8P-Uh.js +206 -0
  22. package/dist/iconMap-V4B8P-Uh.js.map +1 -0
  23. package/dist/icons-CIsIOZXR.js +0 -0
  24. package/dist/icons.d.ts +2 -0
  25. package/dist/icons.js +4 -0
  26. package/dist/index-BNmNIWBL.d.ts +71 -0
  27. package/dist/index-BNmNIWBL.d.ts.map +1 -0
  28. package/dist/index-Bryv_GCG.d.ts +1481 -0
  29. package/dist/index-Bryv_GCG.d.ts.map +1 -0
  30. package/dist/index-CuQIjSXs.d.ts +134 -0
  31. package/dist/index-CuQIjSXs.d.ts.map +1 -0
  32. package/dist/index-DSu19mq0.d.ts +153 -0
  33. package/dist/index-DSu19mq0.d.ts.map +1 -0
  34. package/dist/index-DmsyeHFr.d.ts +149 -0
  35. package/dist/index-DmsyeHFr.d.ts.map +1 -0
  36. package/dist/index-DxnJ8FYM.d.ts +17 -0
  37. package/dist/index-DxnJ8FYM.d.ts.map +1 -0
  38. package/dist/index-DzfY1Tok.d.ts +32 -0
  39. package/dist/index-DzfY1Tok.d.ts.map +1 -0
  40. package/dist/index-Ml_SgiKa.d.ts +1847 -0
  41. package/dist/index-Ml_SgiKa.d.ts.map +1 -0
  42. package/dist/index-kHr9udZD.d.ts +1025 -0
  43. package/dist/index-kHr9udZD.d.ts.map +1 -0
  44. package/dist/index.d.ts +11 -0
  45. package/dist/index.js +15 -0
  46. package/dist/layout-Ca_4r8ka.js +89 -0
  47. package/dist/layout-Ca_4r8ka.js.map +1 -0
  48. package/dist/layout.d.ts +2 -0
  49. package/dist/layout.js +5 -0
  50. package/dist/list-CxfT6hix.js +6831 -0
  51. package/dist/list-CxfT6hix.js.map +1 -0
  52. package/dist/list.d.ts +2 -0
  53. package/dist/list.js +5 -0
  54. package/dist/media-DZ292aKK.js +557 -0
  55. package/dist/media-DZ292aKK.js.map +1 -0
  56. package/dist/media.d.ts +3 -0
  57. package/dist/media.js +3 -0
  58. package/dist/tree-Dd9Z0Aso.js +3351 -0
  59. package/dist/tree-Dd9Z0Aso.js.map +1 -0
  60. package/dist/tree.d.ts +2 -0
  61. package/dist/tree.js +6 -0
  62. package/dist/types-common-CB3kRek8.d.ts +26 -0
  63. package/dist/types-common-CB3kRek8.d.ts.map +1 -0
  64. package/dist/utils-B4fdKKsy.js +3 -0
  65. package/package.json +109 -0
  66. package/src/calendar/AgendaView.tsx +37 -0
  67. package/src/calendar/CalendarBrowser.tsx +90 -0
  68. package/src/calendar/CalendarModel.ts +142 -0
  69. package/src/calendar/CalendarSidebar.tsx +81 -0
  70. package/src/calendar/DayView.tsx +76 -0
  71. package/src/calendar/EventCard.tsx +51 -0
  72. package/src/calendar/MockCalendarProvider.ts +98 -0
  73. package/src/calendar/MonthView.tsx +77 -0
  74. package/src/calendar/WeekView.tsx +129 -0
  75. package/src/calendar/index.ts +18 -0
  76. package/src/calendar/types.ts +25 -0
  77. package/src/contacts/ContactAvatar.tsx +35 -0
  78. package/src/contacts/ContactBrowser.tsx +56 -0
  79. package/src/contacts/ContactCard.tsx +37 -0
  80. package/src/contacts/ContactDetail.tsx +63 -0
  81. package/src/contacts/ContactGroupSidebar.tsx +40 -0
  82. package/src/contacts/ContactList.tsx +32 -0
  83. package/src/contacts/ContactListModel.ts +120 -0
  84. package/src/contacts/MockContactProvider.ts +77 -0
  85. package/src/contacts/index.ts +17 -0
  86. package/src/contacts/types.ts +26 -0
  87. package/src/demos/CalendarBrowserDemo.tsx +15 -0
  88. package/src/demos/ContactBrowserDemo.tsx +15 -0
  89. package/src/demos/MediaBrowserDemo.tsx +15 -0
  90. package/src/file-browser/adapters/DocumentViewerAdapter.ts +371 -0
  91. package/src/file-browser/adapters/FileSystemBridge.ts +168 -0
  92. package/src/file-browser/adapters/GitBrowserAdapter.ts +546 -0
  93. package/src/file-browser/adapters/README.md +504 -0
  94. package/src/file-browser/adapters/index.ts +27 -0
  95. package/src/file-browser/adapters/types.ts +70 -0
  96. package/src/file-browser/architecture.md +645 -0
  97. package/src/file-browser/components/CreateItemDialog.tsx +71 -0
  98. package/src/file-browser/components/DeleteConfirmDialog.tsx +58 -0
  99. package/src/file-browser/components/FileBrowser.tsx +473 -0
  100. package/src/file-browser/components/FileBrowserContent.tsx +209 -0
  101. package/src/file-browser/components/FileBrowserHeader.tsx +151 -0
  102. package/src/file-browser/components/FileBrowserToolbar.tsx +145 -0
  103. package/src/file-browser/components/LeftPanel/LeftPanel.tsx +103 -0
  104. package/src/file-browser/components/LeftPanel/LeftPanelTabs.tsx +70 -0
  105. package/src/file-browser/components/LeftPanel/TreeNavigationView.tsx +256 -0
  106. package/src/file-browser/components/PreviewPane.tsx +146 -0
  107. package/src/file-browser/components/RightPanel/FilePreview.tsx +219 -0
  108. package/src/file-browser/components/RightPanel/RightPanel.tsx +186 -0
  109. package/src/file-browser/components/RightPanel/RightPanelToolbar.tsx +113 -0
  110. package/src/file-browser/components/UploadProgress.tsx +123 -0
  111. package/src/file-browser/components/ViewerHost.tsx +208 -0
  112. package/src/file-browser/components/mobile/MobileNavigation.tsx +227 -0
  113. package/src/file-browser/components/navigation/NavigationButtons.tsx +171 -0
  114. package/src/file-browser/components/shared/ErrorBoundary.tsx +116 -0
  115. package/src/file-browser/components/shared/FileBrowserItem.tsx +195 -0
  116. package/src/file-browser/components/shared/FileIcon.tsx +169 -0
  117. package/src/file-browser/components/toolbar/ViewModeToggle.tsx +200 -0
  118. package/src/file-browser/components/views/ListView/ListView.tsx +484 -0
  119. package/src/file-browser/components/views/ThumbnailView/ThumbnailView.tsx +323 -0
  120. package/src/file-browser/components/views/TreeView/TreeNode.tsx +186 -0
  121. package/src/file-browser/components/views/TreeView/TreeNodeList.tsx +191 -0
  122. package/src/file-browser/components/views/TreeView/TreeView.tsx +200 -0
  123. package/src/file-browser/components/views/TreemapView/TreemapView.tsx +339 -0
  124. package/src/file-browser/context/FileBrowserContext.tsx +13 -0
  125. package/src/file-browser/examples/BasicUsage.tsx +20 -0
  126. package/src/file-browser/index.ts +98 -0
  127. package/src/file-browser/models/FileBrowserModel.ts +623 -0
  128. package/src/file-browser/models/LeftPanelManagerModel.ts +105 -0
  129. package/src/file-browser/models/NavigationManagerModel.ts +312 -0
  130. package/src/file-browser/models/ResponsiveLayoutManagerModel.ts +437 -0
  131. package/src/file-browser/models/RightPanelManagerModel.ts +190 -0
  132. package/src/file-browser/models/SelectionManagerModel.ts +252 -0
  133. package/src/file-browser/models/ToolbarManagerModel.ts +144 -0
  134. package/src/file-browser/models/UploadModel.ts +147 -0
  135. package/src/file-browser/models/ViewModeManagerModel.ts +185 -0
  136. package/src/file-browser/models/ViewerHostModel.ts +44 -0
  137. package/src/file-browser/models/ui/ListViewUIModel.ts +265 -0
  138. package/src/file-browser/models/ui/PreviewUIModel.ts +297 -0
  139. package/src/file-browser/models/ui/ThumbnailViewUIModel.ts +254 -0
  140. package/src/file-browser/models/ui/TreeViewUIModel.ts +128 -0
  141. package/src/file-browser/models/ui/TreemapViewUIModel.ts +350 -0
  142. package/src/file-browser/providers/FileSystemListProvider.ts +552 -0
  143. package/src/file-browser/providers/FileSystemProvider.ts +401 -0
  144. package/src/file-browser/providers/FileSystemTreeProvider.ts +231 -0
  145. package/src/file-browser/providers/GitProvider.ts +337 -0
  146. package/src/file-browser/providers/GitRepositoryProvider.ts +376 -0
  147. package/src/file-browser/providers/IFileBrowserProvider.ts +56 -0
  148. package/src/file-browser/providers/MemoryProvider.ts +303 -0
  149. package/src/file-browser/providers/index.ts +4 -0
  150. package/src/file-browser/registry/ViewerRegistry.ts +551 -0
  151. package/src/file-browser/registry/types.ts +144 -0
  152. package/src/file-browser/scripts/performanceBenchmark.ts +553 -0
  153. package/src/file-browser/services/ThumbnailCacheService.ts +128 -0
  154. package/src/file-browser/tasks.md +537 -0
  155. package/src/file-browser/types/FileBrowserTypes.ts +126 -0
  156. package/src/file-browser/types/ProviderTypes.ts +155 -0
  157. package/src/file-browser/types/UITypes.ts +235 -0
  158. package/src/file-browser/types/ViewModeTypes.ts +150 -0
  159. package/src/file-browser/utils/gestures.ts +327 -0
  160. package/src/file-browser/utils/performance.ts +563 -0
  161. package/src/file-browser/viewers/ImageViewer.tsx +163 -0
  162. package/src/file-browser/viewers/ImageViewerModel.ts +79 -0
  163. package/src/file-browser/viewers/TextViewer.tsx +95 -0
  164. package/src/file-browser/viewers/UnsupportedFileViewer.tsx +57 -0
  165. package/src/file-browser/viewers/index.ts +61 -0
  166. package/src/git/BranchList.tsx +128 -0
  167. package/src/git/CommitGraph.tsx +239 -0
  168. package/src/git/CommitList.tsx +258 -0
  169. package/src/git/DiffViewer.tsx +219 -0
  170. package/src/git/index.ts +4 -0
  171. package/src/icons/iconMap.ts +146 -0
  172. package/src/icons/index.ts +9 -0
  173. package/src/index.ts +13 -0
  174. package/src/layout/README.md +307 -0
  175. package/src/layout/components/ExplorerLayout/ExplorerLayout.tsx +178 -0
  176. package/src/layout/examples/SimpleExample.tsx +60 -0
  177. package/src/layout/index.ts +6 -0
  178. package/src/lib/utils.ts +1 -0
  179. package/src/list/README.md +303 -0
  180. package/src/list/architecture.md +807 -0
  181. package/src/list/components/CalculatedGridView.tsx +252 -0
  182. package/src/list/components/DragPreview.tsx +102 -0
  183. package/src/list/components/ListContextMenu.tsx +274 -0
  184. package/src/list/components/ListItem.tsx +761 -0
  185. package/src/list/components/ListItems.tsx +919 -0
  186. package/src/list/components/MasonryView.tsx +241 -0
  187. package/src/list/components/SearchFilter.tsx +44 -0
  188. package/src/list/components/TreemapView.tsx +709 -0
  189. package/src/list/components/ViewSizeControls.tsx +205 -0
  190. package/src/list/components/ViewTypeSelector.tsx +312 -0
  191. package/src/list/components/VirtualizedDetailsView.tsx +231 -0
  192. package/src/list/components/VirtualizedGrid.tsx +164 -0
  193. package/src/list/components/VirtualizedList.tsx +154 -0
  194. package/src/list/components/VirtualizedMasonryView.tsx +344 -0
  195. package/src/list/components/shared/EmptyState.tsx +103 -0
  196. package/src/list/components/shared/ErrorBoundary.tsx +123 -0
  197. package/src/list/components/shared/ErrorDisplay.tsx +100 -0
  198. package/src/list/components/shared/ListLoader.tsx +146 -0
  199. package/src/list/components/shared/LoadingIndicator.tsx +80 -0
  200. package/src/list/index.ts +92 -0
  201. package/src/list/models/ListItemsModel.ts +1301 -0
  202. package/src/list/models/TreemapModel.ts +204 -0
  203. package/src/list/providers/ListItemsProvider.ts +313 -0
  204. package/src/list/providers/TestListProvider.ts +604 -0
  205. package/src/list/tasks.md +937 -0
  206. package/src/list/types/ListTypes.ts +178 -0
  207. package/src/list/utils/BenchmarkLogger.ts +243 -0
  208. package/src/list/utils/DragDropManager.ts +320 -0
  209. package/src/list/utils/GridLayoutCalculator.ts +290 -0
  210. package/src/list/utils/ListAccessibility.ts +367 -0
  211. package/src/list/utils/ListKeyboard.ts +414 -0
  212. package/src/list/utils/MasonryLayoutCalculator.ts +302 -0
  213. package/src/list/utils/MasonryLayoutEngine.ts +401 -0
  214. package/src/list/utils/__tests__/MasonryLayoutEngine.test.ts +157 -0
  215. package/src/list/utils/__tests__/VirtualizedMasonryView.test.tsx +251 -0
  216. package/src/media/AlbumSidebar.tsx +48 -0
  217. package/src/media/MediaBrowser.tsx +92 -0
  218. package/src/media/MediaBrowserModel.ts +138 -0
  219. package/src/media/MediaGrid.tsx +50 -0
  220. package/src/media/MediaList.tsx +49 -0
  221. package/src/media/MediaPreview.tsx +63 -0
  222. package/src/media/MediaTimeline.tsx +38 -0
  223. package/src/media/MockMediaProvider.ts +70 -0
  224. package/src/media/index.ts +18 -0
  225. package/src/media/types.ts +21 -0
  226. package/src/styles/variables.css +60 -0
  227. package/src/tree/DEVELOPMENT_SUMMARY.md +170 -0
  228. package/src/tree/__tests__/TreeModel.test.ts +16 -0
  229. package/src/tree/architecture.md +530 -0
  230. package/src/tree/components/Tree.tsx +283 -0
  231. package/src/tree/components/TreeCheckbox.tsx +147 -0
  232. package/src/tree/components/TreeContextMenu.tsx +139 -0
  233. package/src/tree/components/TreeNodeList.tsx +329 -0
  234. package/src/tree/components/TreeTable.tsx +382 -0
  235. package/src/tree/index.ts +58 -0
  236. package/src/tree/models/TreeModel.ts +839 -0
  237. package/src/tree/providers/SimpleTreeProvider.ts +463 -0
  238. package/src/tree/providers/TestTreeProvider.ts +946 -0
  239. package/src/tree/providers/TreeProvider.ts +308 -0
  240. package/src/tree/tasks.md +2046 -0
  241. package/src/tree/types/TreeTypes.ts +279 -0
  242. package/src/tree/utils/SelectionTheme.ts +150 -0
  243. package/src/tree/utils/logger.ts +203 -0
  244. package/src/types-common.ts +21 -0
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Core Type Definitions for ListItemsComponent
3
+ *
4
+ * Defines the fundamental interfaces and types used throughout the component.
5
+ * These types support the provider pattern and multiple view types.
6
+ */
7
+
8
+ // AICODE-NOTE: Basic item data structure that must be flexible for different use cases
9
+ export interface ListItemData {
10
+ /** Unique identifier for the item */
11
+ id: string;
12
+ /** Display name of the item */
13
+ name: string;
14
+ /** Optional type classification (file, folder, etc.) */
15
+ type?: string;
16
+ /** Optional size in bytes */
17
+ size?: number;
18
+ /** Optional modification date */
19
+ modified?: Date;
20
+ /** Optional icon identifier or URL */
21
+ icon?: string;
22
+ /** Optional thumbnail URL */
23
+ thumbnail?: string;
24
+ /** Optional thumbnail URL (alias for image display) */
25
+ thumbnailUrl?: string;
26
+ /** Additional custom properties */
27
+ [key: string]: any;
28
+ isDirectory?: boolean;
29
+ children?: ListItemData[];
30
+ metadata?: Record<string, any>;
31
+
32
+ // AICODE-NOTE: Variable dimensions and image support
33
+ imageUrl?: string;
34
+ aspectRatio?: number;
35
+ getDimensions?(): { width: number; height: number };
36
+ }
37
+
38
+ // AICODE-NOTE: Options for loading items, supports filtering, sorting, and pagination
39
+ export interface ListLoadOptions {
40
+ /** Number of items to load (for pagination) */
41
+ limit?: number;
42
+ /** Starting offset for pagination */
43
+ offset?: number;
44
+ /** Search query to filter items */
45
+ searchQuery?: string;
46
+ /** Sort field */
47
+ sortBy?: string;
48
+ /** Sort direction */
49
+ sortDirection?: 'asc' | 'desc';
50
+ /** Additional filter criteria */
51
+ filters?: Record<string, any>;
52
+ }
53
+
54
+ // AICODE-NOTE: Result from loading items, includes total count for virtualization
55
+ export interface ListLoadResult {
56
+ /** Array of loaded items */
57
+ items: ListItemData[];
58
+ /** Total number of items available (for virtualization) */
59
+ totalCount?: number;
60
+ /** Whether there are more items to load */
61
+ hasMore?: boolean;
62
+ /** Loading cursor for pagination */
63
+ nextCursor?: string;
64
+ }
65
+
66
+ // AICODE-NOTE: Selection information passed to provider callbacks
67
+ export interface ListSelectionInfo {
68
+ /** Currently selected items */
69
+ selectedItems: ListItemData[];
70
+ /** Previously selected items */
71
+ previousSelection: ListItemData[];
72
+ /** Type of selection operation */
73
+ selectionType: 'single' | 'multi' | 'range';
74
+ /** What triggered the selection change */
75
+ trigger: 'click' | 'keyboard' | 'api';
76
+ }
77
+
78
+ // AICODE-NOTE: Information about drag and drop operations
79
+ export interface ListDragDropInfo {
80
+ /** Items being dragged */
81
+ draggedItems: ListItemData[];
82
+ /** Target item being dropped on */
83
+ targetItem: ListItemData | null;
84
+ /** Drop position relative to target */
85
+ position: 'before' | 'after' | 'inside';
86
+ /** Original drag event */
87
+ event: DragEvent;
88
+ }
89
+
90
+ // AICODE-NOTE: Configuration for virtualization to handle huge datasets
91
+ export interface VirtualizationConfig {
92
+ /** Fixed item height for current view type */
93
+ itemHeight: number;
94
+ /** Items to render outside visible area */
95
+ overscan?: number;
96
+ /** Minimum items before enabling virtualization */
97
+ threshold?: number;
98
+ /** Dynamic loading range size */
99
+ rangeSize?: number;
100
+ }
101
+
102
+ // AICODE-NOTE: Extended view type definition supporting custom renderers
103
+ export interface ListViewType {
104
+ /** Unique identifier for the view type */
105
+ readonly id: string;
106
+ /** Human-readable name */
107
+ readonly name: string;
108
+ /** Optional icon for the view type */
109
+ readonly icon?: string;
110
+ /** Number of items per row (1 for list, 'auto' for responsive grid) */
111
+ readonly itemsPerRow?: number | 'auto' | 'custom';
112
+ /** Whether to show detailed information */
113
+ readonly showDetails?: boolean;
114
+ /** Whether to show thumbnails */
115
+ readonly showThumbnails?: boolean;
116
+ /** Available thumbnail sizes */
117
+ readonly thumbnailSizes?: ThumbnailSize[];
118
+ /** Column definitions for details view */
119
+ readonly columns?: string[];
120
+ /** Custom renderer for this view type */
121
+ readonly customRenderer?: any;
122
+ }
123
+
124
+ // AICODE-NOTE: Thumbnail size options for grid and thumbnail views
125
+ export type ThumbnailSize = 'small' | 'medium' | 'large' | 'extra-large';
126
+
127
+ // AICODE-NOTE: Context menu item definition
128
+ export interface ListContextMenuItem {
129
+ /** Menu item identifier */
130
+ id: string;
131
+ /** Display label */
132
+ label: string;
133
+ /** Optional icon (string or React component) */
134
+ icon?: string | React.ComponentType<any>;
135
+ /** Whether item is disabled */
136
+ disabled?: boolean;
137
+ /** Whether this is a separator */
138
+ type?: 'item' | 'separator';
139
+ /** Whether this is a destructive action */
140
+ destructive?: boolean;
141
+ /** Tooltip text */
142
+ tooltip?: string;
143
+ /** Keyboard shortcut display */
144
+ shortcut?: string;
145
+ /** Submenu items */
146
+ submenu?: ListContextMenuItem[];
147
+ }
148
+
149
+ // AICODE-NOTE: Item renderer interface for custom rendering
150
+ export interface ListItemRenderer {
151
+ /** Render item as text (for non-React environments) */
152
+ renderText?(item: ListItemData): string;
153
+ /** Render item icon */
154
+ renderIcon?(item: ListItemData): string;
155
+ /** Render item thumbnail */
156
+ renderThumbnail?(item: ListItemData): string;
157
+ /** Get display properties */
158
+ getDisplayProps?(item: ListItemData): {
159
+ className?: string;
160
+ style?: React.CSSProperties;
161
+ title?: string;
162
+ ariaLabel?: string;
163
+ };
164
+ /** Custom React component for item rendering */
165
+ renderComponent?: React.ComponentType<{ item: ListItemData; [key: string]: any }>;
166
+ }
167
+
168
+ // AICODE-NOTE: Error information for graceful error handling
169
+ export interface ListError {
170
+ /** Error message */
171
+ message: string;
172
+ /** Error code */
173
+ code?: string;
174
+ /** Whether error is recoverable */
175
+ recoverable?: boolean;
176
+ /** Retry function */
177
+ retry?: () => void;
178
+ }
@@ -0,0 +1,243 @@
1
+ // AICODE-NOTE: Benchmark logging utility for performance monitoring and optimization
2
+
3
+ export interface BenchmarkResult {
4
+ operation: string;
5
+ duration: number;
6
+ timestamp: number;
7
+ metadata?: Record<string, any>;
8
+ }
9
+
10
+ export interface BenchmarkReport {
11
+ totalOperations: number;
12
+ totalDuration: number;
13
+ averageDuration: number;
14
+ slowestOperation: BenchmarkResult | null;
15
+ fastestOperation: BenchmarkResult | null;
16
+ operations: BenchmarkResult[];
17
+ }
18
+
19
+ export class BenchmarkLogger {
20
+ private results: BenchmarkResult[] = [];
21
+ private activeTimers = new Map<string, number>();
22
+ private enabled: boolean = true;
23
+
24
+ constructor(enabled: boolean = true) {
25
+ this.enabled = enabled;
26
+ }
27
+
28
+ /**
29
+ * Start timing an operation
30
+ */
31
+ start(operation: string, metadata?: Record<string, any>): void {
32
+ if (!this.enabled) return;
33
+
34
+ const startTime = performance.now();
35
+ this.activeTimers.set(operation, startTime);
36
+
37
+ if (metadata) {
38
+ console.log(`šŸš€ [BENCHMARK] Starting: ${operation}`, metadata);
39
+ } else {
40
+ console.log(`šŸš€ [BENCHMARK] Starting: ${operation}`);
41
+ }
42
+ }
43
+
44
+ /**
45
+ * End timing an operation and log the result
46
+ */
47
+ end(operation: string, metadata?: Record<string, any>): number {
48
+ if (!this.enabled) return 0;
49
+
50
+ const startTime = this.activeTimers.get(operation);
51
+ if (!startTime) {
52
+ console.warn(`āš ļø [BENCHMARK] No start time found for operation: ${operation}`);
53
+ return 0;
54
+ }
55
+
56
+ const endTime = performance.now();
57
+ const duration = endTime - startTime;
58
+
59
+ const result: BenchmarkResult = {
60
+ operation,
61
+ duration,
62
+ timestamp: Date.now(),
63
+ metadata
64
+ };
65
+
66
+ this.results.push(result);
67
+ this.activeTimers.delete(operation);
68
+
69
+ // Color-coded logging based on duration
70
+ const color = this.getDurationColor(duration);
71
+ const formattedDuration = this.formatDuration(duration);
72
+
73
+ if (metadata) {
74
+ console.log(`${color} [BENCHMARK] Completed: ${operation} in ${formattedDuration}`, metadata);
75
+ } else {
76
+ console.log(`${color} [BENCHMARK] Completed: ${operation} in ${formattedDuration}`);
77
+ }
78
+
79
+ return duration;
80
+ }
81
+
82
+ /**
83
+ * Time a synchronous operation
84
+ */
85
+ time<T>(operation: string, fn: () => T, metadata?: Record<string, any>): T {
86
+ this.start(operation, metadata);
87
+ try {
88
+ const result = fn();
89
+ this.end(operation, metadata);
90
+ return result;
91
+ } catch (error) {
92
+ this.end(operation, { ...metadata, error: error instanceof Error ? error.message : String(error) });
93
+ throw error;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Time an asynchronous operation
99
+ */
100
+ async timeAsync<T>(operation: string, fn: () => Promise<T>, metadata?: Record<string, any>): Promise<T> {
101
+ this.start(operation, metadata);
102
+ try {
103
+ const result = await fn();
104
+ this.end(operation, metadata);
105
+ return result;
106
+ } catch (error) {
107
+ this.end(operation, { ...metadata, error: error instanceof Error ? error.message : String(error) });
108
+ throw error;
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Get a performance report
114
+ */
115
+ getReport(): BenchmarkReport {
116
+ if (this.results.length === 0) {
117
+ return {
118
+ totalOperations: 0,
119
+ totalDuration: 0,
120
+ averageDuration: 0,
121
+ slowestOperation: null,
122
+ fastestOperation: null,
123
+ operations: []
124
+ };
125
+ }
126
+
127
+ const totalDuration = this.results.reduce((sum, result) => sum + result.duration, 0);
128
+ const averageDuration = totalDuration / this.results.length;
129
+
130
+ const sortedByDuration = [...this.results].sort((a, b) => a.duration - b.duration);
131
+ const fastestOperation = sortedByDuration[0] || null;
132
+ const slowestOperation = sortedByDuration[sortedByDuration.length - 1] || null;
133
+
134
+ return {
135
+ totalOperations: this.results.length,
136
+ totalDuration,
137
+ averageDuration,
138
+ slowestOperation,
139
+ fastestOperation,
140
+ operations: [...this.results]
141
+ };
142
+ }
143
+
144
+ /**
145
+ * Log a performance report
146
+ */
147
+ logReport(): void {
148
+ if (!this.enabled) return;
149
+
150
+ const report = this.getReport();
151
+
152
+ console.group('šŸ“Š [BENCHMARK] Performance Report');
153
+ console.log(`Total Operations: ${report.totalOperations}`);
154
+ console.log(`Total Duration: ${this.formatDuration(report.totalDuration)}`);
155
+ console.log(`Average Duration: ${this.formatDuration(report.averageDuration)}`);
156
+
157
+ if (report.slowestOperation) {
158
+ console.log(`Slowest: ${report.slowestOperation.operation} (${this.formatDuration(report.slowestOperation.duration)})`);
159
+ }
160
+
161
+ if (report.fastestOperation) {
162
+ console.log(`Fastest: ${report.fastestOperation.operation} (${this.formatDuration(report.fastestOperation.duration)})`);
163
+ }
164
+
165
+ // Group operations by name
166
+ const operationGroups = this.groupOperationsByName(report.operations);
167
+ console.log('\nšŸ“ˆ Operations Summary:');
168
+
169
+ Object.entries(operationGroups).forEach(([name, operations]) => {
170
+ const avgDuration = operations.reduce((sum, op) => sum + op.duration, 0) / operations.length;
171
+ console.log(` ${name}: ${operations.length}x, avg ${this.formatDuration(avgDuration)}`);
172
+ });
173
+
174
+ console.groupEnd();
175
+ }
176
+
177
+ /**
178
+ * Clear all benchmark results
179
+ */
180
+ clear(): void {
181
+ this.results = [];
182
+ this.activeTimers.clear();
183
+ }
184
+
185
+ /**
186
+ * Enable or disable benchmarking
187
+ */
188
+ setEnabled(enabled: boolean): void {
189
+ this.enabled = enabled;
190
+ }
191
+
192
+ /**
193
+ * Check if benchmarking is enabled
194
+ */
195
+ isEnabled(): boolean {
196
+ return this.enabled;
197
+ }
198
+
199
+ private getDurationColor(duration: number): string {
200
+ if (duration < 1) return '🟢'; // Green - very fast
201
+ if (duration < 10) return '🟔'; // Yellow - fast
202
+ if (duration < 50) return '🟠'; // Orange - moderate
203
+ return 'šŸ”“'; // Red - slow
204
+ }
205
+
206
+ private formatDuration(duration: number): string {
207
+ if (duration < 1) {
208
+ return `${duration.toFixed(3)}ms`;
209
+ } else if (duration < 1000) {
210
+ return `${duration.toFixed(1)}ms`;
211
+ } else {
212
+ return `${(duration / 1000).toFixed(2)}s`;
213
+ }
214
+ }
215
+
216
+ private groupOperationsByName(operations: BenchmarkResult[]): Record<string, BenchmarkResult[]> {
217
+ return operations.reduce((groups, operation) => {
218
+ const name = operation.operation;
219
+ if (!groups[name]) {
220
+ groups[name] = [];
221
+ }
222
+ groups[name].push(operation);
223
+ return groups;
224
+ }, {} as Record<string, BenchmarkResult[]>);
225
+ }
226
+ }
227
+
228
+ // AICODE-NOTE: Global benchmark logger instance
229
+ export const benchmarkLogger = new BenchmarkLogger(
230
+ typeof window !== 'undefined' &&
231
+ (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1')
232
+ );
233
+
234
+ // AICODE-NOTE: Convenience functions for common benchmarking patterns
235
+ export const benchmark = {
236
+ start: (operation: string, metadata?: Record<string, any>) => benchmarkLogger.start(operation, metadata),
237
+ end: (operation: string, metadata?: Record<string, any>) => benchmarkLogger.end(operation, metadata),
238
+ time: <T>(operation: string, fn: () => T, metadata?: Record<string, any>) => benchmarkLogger.time(operation, fn, metadata),
239
+ timeAsync: <T>(operation: string, fn: () => Promise<T>, metadata?: Record<string, any>) => benchmarkLogger.timeAsync(operation, fn, metadata),
240
+ report: () => benchmarkLogger.logReport(),
241
+ clear: () => benchmarkLogger.clear(),
242
+ setEnabled: (enabled: boolean) => benchmarkLogger.setEnabled(enabled)
243
+ };