@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.
- package/dist/ExplorerLayout-CSIJd7N4.js +105 -0
- package/dist/ExplorerLayout-CSIJd7N4.js.map +1 -0
- package/dist/FileBrowserContext-B6jixa2j.js +11 -0
- package/dist/FileBrowserContext-B6jixa2j.js.map +1 -0
- package/dist/calendar-DSlrbHoj.js +761 -0
- package/dist/calendar-DSlrbHoj.js.map +1 -0
- package/dist/calendar.d.ts +3 -0
- package/dist/calendar.js +3 -0
- package/dist/contacts-DQXTZzHc.js +539 -0
- package/dist/contacts-DQXTZzHc.js.map +1 -0
- package/dist/contacts.d.ts +3 -0
- package/dist/contacts.js +3 -0
- package/dist/file-browser-m5atC3kF.js +6755 -0
- package/dist/file-browser-m5atC3kF.js.map +1 -0
- package/dist/file-browser.d.ts +11 -0
- package/dist/file-browser.js +9 -0
- package/dist/git-B55e6LL-.js +561 -0
- package/dist/git-B55e6LL-.js.map +1 -0
- package/dist/git.d.ts +2 -0
- package/dist/git.js +3 -0
- package/dist/iconMap-V4B8P-Uh.js +206 -0
- package/dist/iconMap-V4B8P-Uh.js.map +1 -0
- package/dist/icons-CIsIOZXR.js +0 -0
- package/dist/icons.d.ts +2 -0
- package/dist/icons.js +4 -0
- package/dist/index-BNmNIWBL.d.ts +71 -0
- package/dist/index-BNmNIWBL.d.ts.map +1 -0
- package/dist/index-Bryv_GCG.d.ts +1481 -0
- package/dist/index-Bryv_GCG.d.ts.map +1 -0
- package/dist/index-CuQIjSXs.d.ts +134 -0
- package/dist/index-CuQIjSXs.d.ts.map +1 -0
- package/dist/index-DSu19mq0.d.ts +153 -0
- package/dist/index-DSu19mq0.d.ts.map +1 -0
- package/dist/index-DmsyeHFr.d.ts +149 -0
- package/dist/index-DmsyeHFr.d.ts.map +1 -0
- package/dist/index-DxnJ8FYM.d.ts +17 -0
- package/dist/index-DxnJ8FYM.d.ts.map +1 -0
- package/dist/index-DzfY1Tok.d.ts +32 -0
- package/dist/index-DzfY1Tok.d.ts.map +1 -0
- package/dist/index-Ml_SgiKa.d.ts +1847 -0
- package/dist/index-Ml_SgiKa.d.ts.map +1 -0
- package/dist/index-kHr9udZD.d.ts +1025 -0
- package/dist/index-kHr9udZD.d.ts.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +15 -0
- package/dist/layout-Ca_4r8ka.js +89 -0
- package/dist/layout-Ca_4r8ka.js.map +1 -0
- package/dist/layout.d.ts +2 -0
- package/dist/layout.js +5 -0
- package/dist/list-CxfT6hix.js +6831 -0
- package/dist/list-CxfT6hix.js.map +1 -0
- package/dist/list.d.ts +2 -0
- package/dist/list.js +5 -0
- package/dist/media-DZ292aKK.js +557 -0
- package/dist/media-DZ292aKK.js.map +1 -0
- package/dist/media.d.ts +3 -0
- package/dist/media.js +3 -0
- package/dist/tree-Dd9Z0Aso.js +3351 -0
- package/dist/tree-Dd9Z0Aso.js.map +1 -0
- package/dist/tree.d.ts +2 -0
- package/dist/tree.js +6 -0
- package/dist/types-common-CB3kRek8.d.ts +26 -0
- package/dist/types-common-CB3kRek8.d.ts.map +1 -0
- package/dist/utils-B4fdKKsy.js +3 -0
- package/package.json +109 -0
- package/src/calendar/AgendaView.tsx +37 -0
- package/src/calendar/CalendarBrowser.tsx +90 -0
- package/src/calendar/CalendarModel.ts +142 -0
- package/src/calendar/CalendarSidebar.tsx +81 -0
- package/src/calendar/DayView.tsx +76 -0
- package/src/calendar/EventCard.tsx +51 -0
- package/src/calendar/MockCalendarProvider.ts +98 -0
- package/src/calendar/MonthView.tsx +77 -0
- package/src/calendar/WeekView.tsx +129 -0
- package/src/calendar/index.ts +18 -0
- package/src/calendar/types.ts +25 -0
- package/src/contacts/ContactAvatar.tsx +35 -0
- package/src/contacts/ContactBrowser.tsx +56 -0
- package/src/contacts/ContactCard.tsx +37 -0
- package/src/contacts/ContactDetail.tsx +63 -0
- package/src/contacts/ContactGroupSidebar.tsx +40 -0
- package/src/contacts/ContactList.tsx +32 -0
- package/src/contacts/ContactListModel.ts +120 -0
- package/src/contacts/MockContactProvider.ts +77 -0
- package/src/contacts/index.ts +17 -0
- package/src/contacts/types.ts +26 -0
- package/src/demos/CalendarBrowserDemo.tsx +15 -0
- package/src/demos/ContactBrowserDemo.tsx +15 -0
- package/src/demos/MediaBrowserDemo.tsx +15 -0
- package/src/file-browser/adapters/DocumentViewerAdapter.ts +371 -0
- package/src/file-browser/adapters/FileSystemBridge.ts +168 -0
- package/src/file-browser/adapters/GitBrowserAdapter.ts +546 -0
- package/src/file-browser/adapters/README.md +504 -0
- package/src/file-browser/adapters/index.ts +27 -0
- package/src/file-browser/adapters/types.ts +70 -0
- package/src/file-browser/architecture.md +645 -0
- package/src/file-browser/components/CreateItemDialog.tsx +71 -0
- package/src/file-browser/components/DeleteConfirmDialog.tsx +58 -0
- package/src/file-browser/components/FileBrowser.tsx +473 -0
- package/src/file-browser/components/FileBrowserContent.tsx +209 -0
- package/src/file-browser/components/FileBrowserHeader.tsx +151 -0
- package/src/file-browser/components/FileBrowserToolbar.tsx +145 -0
- package/src/file-browser/components/LeftPanel/LeftPanel.tsx +103 -0
- package/src/file-browser/components/LeftPanel/LeftPanelTabs.tsx +70 -0
- package/src/file-browser/components/LeftPanel/TreeNavigationView.tsx +256 -0
- package/src/file-browser/components/PreviewPane.tsx +146 -0
- package/src/file-browser/components/RightPanel/FilePreview.tsx +219 -0
- package/src/file-browser/components/RightPanel/RightPanel.tsx +186 -0
- package/src/file-browser/components/RightPanel/RightPanelToolbar.tsx +113 -0
- package/src/file-browser/components/UploadProgress.tsx +123 -0
- package/src/file-browser/components/ViewerHost.tsx +208 -0
- package/src/file-browser/components/mobile/MobileNavigation.tsx +227 -0
- package/src/file-browser/components/navigation/NavigationButtons.tsx +171 -0
- package/src/file-browser/components/shared/ErrorBoundary.tsx +116 -0
- package/src/file-browser/components/shared/FileBrowserItem.tsx +195 -0
- package/src/file-browser/components/shared/FileIcon.tsx +169 -0
- package/src/file-browser/components/toolbar/ViewModeToggle.tsx +200 -0
- package/src/file-browser/components/views/ListView/ListView.tsx +484 -0
- package/src/file-browser/components/views/ThumbnailView/ThumbnailView.tsx +323 -0
- package/src/file-browser/components/views/TreeView/TreeNode.tsx +186 -0
- package/src/file-browser/components/views/TreeView/TreeNodeList.tsx +191 -0
- package/src/file-browser/components/views/TreeView/TreeView.tsx +200 -0
- package/src/file-browser/components/views/TreemapView/TreemapView.tsx +339 -0
- package/src/file-browser/context/FileBrowserContext.tsx +13 -0
- package/src/file-browser/examples/BasicUsage.tsx +20 -0
- package/src/file-browser/index.ts +98 -0
- package/src/file-browser/models/FileBrowserModel.ts +623 -0
- package/src/file-browser/models/LeftPanelManagerModel.ts +105 -0
- package/src/file-browser/models/NavigationManagerModel.ts +312 -0
- package/src/file-browser/models/ResponsiveLayoutManagerModel.ts +437 -0
- package/src/file-browser/models/RightPanelManagerModel.ts +190 -0
- package/src/file-browser/models/SelectionManagerModel.ts +252 -0
- package/src/file-browser/models/ToolbarManagerModel.ts +144 -0
- package/src/file-browser/models/UploadModel.ts +147 -0
- package/src/file-browser/models/ViewModeManagerModel.ts +185 -0
- package/src/file-browser/models/ViewerHostModel.ts +44 -0
- package/src/file-browser/models/ui/ListViewUIModel.ts +265 -0
- package/src/file-browser/models/ui/PreviewUIModel.ts +297 -0
- package/src/file-browser/models/ui/ThumbnailViewUIModel.ts +254 -0
- package/src/file-browser/models/ui/TreeViewUIModel.ts +128 -0
- package/src/file-browser/models/ui/TreemapViewUIModel.ts +350 -0
- package/src/file-browser/providers/FileSystemListProvider.ts +552 -0
- package/src/file-browser/providers/FileSystemProvider.ts +401 -0
- package/src/file-browser/providers/FileSystemTreeProvider.ts +231 -0
- package/src/file-browser/providers/GitProvider.ts +337 -0
- package/src/file-browser/providers/GitRepositoryProvider.ts +376 -0
- package/src/file-browser/providers/IFileBrowserProvider.ts +56 -0
- package/src/file-browser/providers/MemoryProvider.ts +303 -0
- package/src/file-browser/providers/index.ts +4 -0
- package/src/file-browser/registry/ViewerRegistry.ts +551 -0
- package/src/file-browser/registry/types.ts +144 -0
- package/src/file-browser/scripts/performanceBenchmark.ts +553 -0
- package/src/file-browser/services/ThumbnailCacheService.ts +128 -0
- package/src/file-browser/tasks.md +537 -0
- package/src/file-browser/types/FileBrowserTypes.ts +126 -0
- package/src/file-browser/types/ProviderTypes.ts +155 -0
- package/src/file-browser/types/UITypes.ts +235 -0
- package/src/file-browser/types/ViewModeTypes.ts +150 -0
- package/src/file-browser/utils/gestures.ts +327 -0
- package/src/file-browser/utils/performance.ts +563 -0
- package/src/file-browser/viewers/ImageViewer.tsx +163 -0
- package/src/file-browser/viewers/ImageViewerModel.ts +79 -0
- package/src/file-browser/viewers/TextViewer.tsx +95 -0
- package/src/file-browser/viewers/UnsupportedFileViewer.tsx +57 -0
- package/src/file-browser/viewers/index.ts +61 -0
- package/src/git/BranchList.tsx +128 -0
- package/src/git/CommitGraph.tsx +239 -0
- package/src/git/CommitList.tsx +258 -0
- package/src/git/DiffViewer.tsx +219 -0
- package/src/git/index.ts +4 -0
- package/src/icons/iconMap.ts +146 -0
- package/src/icons/index.ts +9 -0
- package/src/index.ts +13 -0
- package/src/layout/README.md +307 -0
- package/src/layout/components/ExplorerLayout/ExplorerLayout.tsx +178 -0
- package/src/layout/examples/SimpleExample.tsx +60 -0
- package/src/layout/index.ts +6 -0
- package/src/lib/utils.ts +1 -0
- package/src/list/README.md +303 -0
- package/src/list/architecture.md +807 -0
- package/src/list/components/CalculatedGridView.tsx +252 -0
- package/src/list/components/DragPreview.tsx +102 -0
- package/src/list/components/ListContextMenu.tsx +274 -0
- package/src/list/components/ListItem.tsx +761 -0
- package/src/list/components/ListItems.tsx +919 -0
- package/src/list/components/MasonryView.tsx +241 -0
- package/src/list/components/SearchFilter.tsx +44 -0
- package/src/list/components/TreemapView.tsx +709 -0
- package/src/list/components/ViewSizeControls.tsx +205 -0
- package/src/list/components/ViewTypeSelector.tsx +312 -0
- package/src/list/components/VirtualizedDetailsView.tsx +231 -0
- package/src/list/components/VirtualizedGrid.tsx +164 -0
- package/src/list/components/VirtualizedList.tsx +154 -0
- package/src/list/components/VirtualizedMasonryView.tsx +344 -0
- package/src/list/components/shared/EmptyState.tsx +103 -0
- package/src/list/components/shared/ErrorBoundary.tsx +123 -0
- package/src/list/components/shared/ErrorDisplay.tsx +100 -0
- package/src/list/components/shared/ListLoader.tsx +146 -0
- package/src/list/components/shared/LoadingIndicator.tsx +80 -0
- package/src/list/index.ts +92 -0
- package/src/list/models/ListItemsModel.ts +1301 -0
- package/src/list/models/TreemapModel.ts +204 -0
- package/src/list/providers/ListItemsProvider.ts +313 -0
- package/src/list/providers/TestListProvider.ts +604 -0
- package/src/list/tasks.md +937 -0
- package/src/list/types/ListTypes.ts +178 -0
- package/src/list/utils/BenchmarkLogger.ts +243 -0
- package/src/list/utils/DragDropManager.ts +320 -0
- package/src/list/utils/GridLayoutCalculator.ts +290 -0
- package/src/list/utils/ListAccessibility.ts +367 -0
- package/src/list/utils/ListKeyboard.ts +414 -0
- package/src/list/utils/MasonryLayoutCalculator.ts +302 -0
- package/src/list/utils/MasonryLayoutEngine.ts +401 -0
- package/src/list/utils/__tests__/MasonryLayoutEngine.test.ts +157 -0
- package/src/list/utils/__tests__/VirtualizedMasonryView.test.tsx +251 -0
- package/src/media/AlbumSidebar.tsx +48 -0
- package/src/media/MediaBrowser.tsx +92 -0
- package/src/media/MediaBrowserModel.ts +138 -0
- package/src/media/MediaGrid.tsx +50 -0
- package/src/media/MediaList.tsx +49 -0
- package/src/media/MediaPreview.tsx +63 -0
- package/src/media/MediaTimeline.tsx +38 -0
- package/src/media/MockMediaProvider.ts +70 -0
- package/src/media/index.ts +18 -0
- package/src/media/types.ts +21 -0
- package/src/styles/variables.css +60 -0
- package/src/tree/DEVELOPMENT_SUMMARY.md +170 -0
- package/src/tree/__tests__/TreeModel.test.ts +16 -0
- package/src/tree/architecture.md +530 -0
- package/src/tree/components/Tree.tsx +283 -0
- package/src/tree/components/TreeCheckbox.tsx +147 -0
- package/src/tree/components/TreeContextMenu.tsx +139 -0
- package/src/tree/components/TreeNodeList.tsx +329 -0
- package/src/tree/components/TreeTable.tsx +382 -0
- package/src/tree/index.ts +58 -0
- package/src/tree/models/TreeModel.ts +839 -0
- package/src/tree/providers/SimpleTreeProvider.ts +463 -0
- package/src/tree/providers/TestTreeProvider.ts +946 -0
- package/src/tree/providers/TreeProvider.ts +308 -0
- package/src/tree/tasks.md +2046 -0
- package/src/tree/types/TreeTypes.ts +279 -0
- package/src/tree/utils/SelectionTheme.ts +150 -0
- package/src/tree/utils/logger.ts +203 -0
- 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
|
+
};
|