@classic-homes/theme-svelte 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 (124) hide show
  1. package/README.md +305 -0
  2. package/dist/lib/components/Alert.svelte +51 -0
  3. package/dist/lib/components/Alert.svelte.d.ts +9 -0
  4. package/dist/lib/components/AlertDescription.svelte +16 -0
  5. package/dist/lib/components/AlertDescription.svelte.d.ts +9 -0
  6. package/dist/lib/components/AlertDialog.svelte +136 -0
  7. package/dist/lib/components/AlertDialog.svelte.d.ts +79 -0
  8. package/dist/lib/components/AlertTitle.svelte +16 -0
  9. package/dist/lib/components/AlertTitle.svelte.d.ts +9 -0
  10. package/dist/lib/components/Avatar.svelte +56 -0
  11. package/dist/lib/components/Avatar.svelte.d.ts +26 -0
  12. package/dist/lib/components/AvatarFallback.svelte +31 -0
  13. package/dist/lib/components/AvatarFallback.svelte.d.ts +17 -0
  14. package/dist/lib/components/AvatarImage.svelte +29 -0
  15. package/dist/lib/components/AvatarImage.svelte.d.ts +12 -0
  16. package/dist/lib/components/Badge.svelte +73 -0
  17. package/dist/lib/components/Badge.svelte.d.ts +11 -0
  18. package/dist/lib/components/Button.svelte +130 -0
  19. package/dist/lib/components/Button.svelte.d.ts +17 -0
  20. package/dist/lib/components/Card.svelte +58 -0
  21. package/dist/lib/components/Card.svelte.d.ts +26 -0
  22. package/dist/lib/components/CardContent.svelte +16 -0
  23. package/dist/lib/components/CardContent.svelte.d.ts +9 -0
  24. package/dist/lib/components/CardDescription.svelte +16 -0
  25. package/dist/lib/components/CardDescription.svelte.d.ts +9 -0
  26. package/dist/lib/components/CardFooter.svelte +16 -0
  27. package/dist/lib/components/CardFooter.svelte.d.ts +9 -0
  28. package/dist/lib/components/CardHeader.svelte +16 -0
  29. package/dist/lib/components/CardHeader.svelte.d.ts +9 -0
  30. package/dist/lib/components/CardTitle.svelte +16 -0
  31. package/dist/lib/components/CardTitle.svelte.d.ts +9 -0
  32. package/dist/lib/components/Checkbox.svelte +65 -0
  33. package/dist/lib/components/Checkbox.svelte.d.ts +14 -0
  34. package/dist/lib/components/DataTable.svelte +334 -0
  35. package/dist/lib/components/DataTable.svelte.d.ts +103 -0
  36. package/dist/lib/components/Dialog.svelte +111 -0
  37. package/dist/lib/components/Dialog.svelte.d.ts +22 -0
  38. package/dist/lib/components/DropdownMenu.svelte +135 -0
  39. package/dist/lib/components/DropdownMenu.svelte.d.ts +33 -0
  40. package/dist/lib/components/FileUpload.svelte +448 -0
  41. package/dist/lib/components/FileUpload.svelte.d.ts +42 -0
  42. package/dist/lib/components/FormField.svelte +134 -0
  43. package/dist/lib/components/FormField.svelte.d.ts +37 -0
  44. package/dist/lib/components/Input.svelte +61 -0
  45. package/dist/lib/components/Input.svelte.d.ts +19 -0
  46. package/dist/lib/components/Label.svelte +33 -0
  47. package/dist/lib/components/Label.svelte.d.ts +11 -0
  48. package/dist/lib/components/LoadingLogo.svelte +124 -0
  49. package/dist/lib/components/LoadingLogo.svelte.d.ts +16 -0
  50. package/dist/lib/components/LogoMain.svelte +237 -0
  51. package/dist/lib/components/LogoMain.svelte.d.ts +20 -0
  52. package/dist/lib/components/PageHeader.svelte +90 -0
  53. package/dist/lib/components/PageHeader.svelte.d.ts +28 -0
  54. package/dist/lib/components/Section.svelte +44 -0
  55. package/dist/lib/components/Section.svelte.d.ts +28 -0
  56. package/dist/lib/components/Select.svelte +174 -0
  57. package/dist/lib/components/Select.svelte.d.ts +32 -0
  58. package/dist/lib/components/Separator.svelte +29 -0
  59. package/dist/lib/components/Separator.svelte.d.ts +9 -0
  60. package/dist/lib/components/Skeleton.svelte +35 -0
  61. package/dist/lib/components/Skeleton.svelte.d.ts +7 -0
  62. package/dist/lib/components/Spinner.svelte +50 -0
  63. package/dist/lib/components/Spinner.svelte.d.ts +8 -0
  64. package/dist/lib/components/Switch.svelte +56 -0
  65. package/dist/lib/components/Switch.svelte.d.ts +14 -0
  66. package/dist/lib/components/TabPanel.svelte +44 -0
  67. package/dist/lib/components/TabPanel.svelte.d.ts +12 -0
  68. package/dist/lib/components/Tabs.svelte +125 -0
  69. package/dist/lib/components/Tabs.svelte.d.ts +19 -0
  70. package/dist/lib/components/Textarea.svelte +54 -0
  71. package/dist/lib/components/Textarea.svelte.d.ts +16 -0
  72. package/dist/lib/components/Toast.svelte +116 -0
  73. package/dist/lib/components/Toast.svelte.d.ts +12 -0
  74. package/dist/lib/components/ToastContainer.svelte +56 -0
  75. package/dist/lib/components/ToastContainer.svelte.d.ts +8 -0
  76. package/dist/lib/components/Tooltip.svelte +55 -0
  77. package/dist/lib/components/Tooltip.svelte.d.ts +18 -0
  78. package/dist/lib/components/layout/AppShell.svelte +82 -0
  79. package/dist/lib/components/layout/AppShell.svelte.d.ts +44 -0
  80. package/dist/lib/components/layout/DashboardLayout.svelte +248 -0
  81. package/dist/lib/components/layout/DashboardLayout.svelte.d.ts +62 -0
  82. package/dist/lib/components/layout/Footer.svelte +130 -0
  83. package/dist/lib/components/layout/Footer.svelte.d.ts +32 -0
  84. package/dist/lib/components/layout/FormPageLayout.svelte +92 -0
  85. package/dist/lib/components/layout/FormPageLayout.svelte.d.ts +33 -0
  86. package/dist/lib/components/layout/Header.svelte +94 -0
  87. package/dist/lib/components/layout/Header.svelte.d.ts +30 -0
  88. package/dist/lib/components/layout/PublicLayout.svelte +180 -0
  89. package/dist/lib/components/layout/PublicLayout.svelte.d.ts +39 -0
  90. package/dist/lib/components/layout/QuickLinks.svelte +112 -0
  91. package/dist/lib/components/layout/QuickLinks.svelte.d.ts +27 -0
  92. package/dist/lib/components/layout/Sidebar.svelte +243 -0
  93. package/dist/lib/components/layout/Sidebar.svelte.d.ts +48 -0
  94. package/dist/lib/composables/index.d.ts +8 -0
  95. package/dist/lib/composables/index.js +10 -0
  96. package/dist/lib/composables/useAsync.svelte.d.ts +102 -0
  97. package/dist/lib/composables/useAsync.svelte.js +210 -0
  98. package/dist/lib/composables/useForm.svelte.d.ts +123 -0
  99. package/dist/lib/composables/useForm.svelte.js +245 -0
  100. package/dist/lib/index.d.ts +65 -0
  101. package/dist/lib/index.js +83 -0
  102. package/dist/lib/performance.d.ts +79 -0
  103. package/dist/lib/performance.js +170 -0
  104. package/dist/lib/schemas/auth.d.ts +410 -0
  105. package/dist/lib/schemas/auth.js +216 -0
  106. package/dist/lib/schemas/common.d.ts +267 -0
  107. package/dist/lib/schemas/common.js +268 -0
  108. package/dist/lib/schemas/index.d.ts +24 -0
  109. package/dist/lib/schemas/index.js +32 -0
  110. package/dist/lib/stores/sidebar.svelte.d.ts +25 -0
  111. package/dist/lib/stores/sidebar.svelte.js +38 -0
  112. package/dist/lib/stores/theme.svelte.d.ts +72 -0
  113. package/dist/lib/stores/theme.svelte.js +150 -0
  114. package/dist/lib/stores/toast.svelte.d.ts +62 -0
  115. package/dist/lib/stores/toast.svelte.js +93 -0
  116. package/dist/lib/types/components.d.ts +85 -0
  117. package/dist/lib/types/components.js +7 -0
  118. package/dist/lib/types/layout.d.ts +258 -0
  119. package/dist/lib/types/layout.js +7 -0
  120. package/dist/lib/utils.d.ts +6 -0
  121. package/dist/lib/utils.js +9 -0
  122. package/dist/lib/validation.d.ts +101 -0
  123. package/dist/lib/validation.js +170 -0
  124. package/package.json +56 -0
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Classic Theme Svelte Components
3
+ *
4
+ * A collection of accessible, composable Svelte 5 components built on Bits UI
5
+ * and styled with Tailwind CSS using the Classic theme design tokens.
6
+ *
7
+ * All components use Svelte 5 runes syntax ($props, $state, $derived, etc.)
8
+ */
9
+ export { default as Button } from './components/Button.svelte';
10
+ export { default as Input } from './components/Input.svelte';
11
+ export { default as Label } from './components/Label.svelte';
12
+ export { default as Textarea } from './components/Textarea.svelte';
13
+ export { default as Checkbox } from './components/Checkbox.svelte';
14
+ export { default as Switch } from './components/Switch.svelte';
15
+ export { default as Separator } from './components/Separator.svelte';
16
+ export { default as Card } from './components/Card.svelte';
17
+ export { default as CardHeader } from './components/CardHeader.svelte';
18
+ export { default as CardTitle } from './components/CardTitle.svelte';
19
+ export { default as CardDescription } from './components/CardDescription.svelte';
20
+ export { default as CardContent } from './components/CardContent.svelte';
21
+ export { default as CardFooter } from './components/CardFooter.svelte';
22
+ export { default as Alert } from './components/Alert.svelte';
23
+ export { default as AlertTitle } from './components/AlertTitle.svelte';
24
+ export { default as AlertDescription } from './components/AlertDescription.svelte';
25
+ export { default as Badge } from './components/Badge.svelte';
26
+ export { default as Spinner } from './components/Spinner.svelte';
27
+ export { default as Skeleton } from './components/Skeleton.svelte';
28
+ export { default as Toast } from './components/Toast.svelte';
29
+ export { default as ToastContainer } from './components/ToastContainer.svelte';
30
+ export { default as Dialog } from './components/Dialog.svelte';
31
+ export { default as AlertDialog } from './components/AlertDialog.svelte';
32
+ export { default as Tooltip } from './components/Tooltip.svelte';
33
+ export { default as DropdownMenu } from './components/DropdownMenu.svelte';
34
+ export { default as Select } from './components/Select.svelte';
35
+ export { default as FormField } from './components/FormField.svelte';
36
+ export { default as FileUpload } from './components/FileUpload.svelte';
37
+ export { default as DataTable } from './components/DataTable.svelte';
38
+ export { default as Tabs } from './components/Tabs.svelte';
39
+ export { default as TabPanel } from './components/TabPanel.svelte';
40
+ export type { DropdownMenuItem, DropdownMenuGroup, SelectOption, SelectGroup, Tab, FileMetadata, DataTableColumn, } from './types/components.js';
41
+ export { default as LogoMain } from './components/LogoMain.svelte';
42
+ export { default as LoadingLogo } from './components/LoadingLogo.svelte';
43
+ export { default as Avatar } from './components/Avatar.svelte';
44
+ export { default as AvatarImage } from './components/AvatarImage.svelte';
45
+ export { default as AvatarFallback } from './components/AvatarFallback.svelte';
46
+ export { default as Section } from './components/Section.svelte';
47
+ export { default as PageHeader } from './components/PageHeader.svelte';
48
+ export { default as AppShell } from './components/layout/AppShell.svelte';
49
+ export { default as DashboardLayout } from './components/layout/DashboardLayout.svelte';
50
+ export { default as PublicLayout } from './components/layout/PublicLayout.svelte';
51
+ export { default as FormPageLayout } from './components/layout/FormPageLayout.svelte';
52
+ export { default as Sidebar } from './components/layout/Sidebar.svelte';
53
+ export { default as Header } from './components/layout/Header.svelte';
54
+ export { default as Footer } from './components/layout/Footer.svelte';
55
+ export { default as QuickLinks } from './components/layout/QuickLinks.svelte';
56
+ export type { NavItem, NavSection, User, BackLink, QuickLink, QuickLinksProps, DashboardLayoutProps, PublicLayoutProps, FormPageLayoutProps, SidebarProps, HeaderProps, FooterProps, AppShellProps, } from './types/layout.js';
57
+ export { toastStore, type Toast as ToastType, type ToastInput } from './stores/toast.svelte.js';
58
+ export { sidebarStore } from './stores/sidebar.svelte.js';
59
+ export { themeStore, type ThemeMode } from './stores/theme.svelte.js';
60
+ export { cn } from './utils.js';
61
+ export { tv, type VariantProps } from 'tailwind-variants';
62
+ export { validateNonEmptyArray, validateRequired, validateOneOf, validateRange, validateProps, createValidator, type ValidationResult, } from './validation.js';
63
+ export { perfStart, perfEnd, measure, measureAsync, getPerformanceEntries, clearPerformanceEntries, createPerfMonitor, type PerformanceMark, } from './performance.js';
64
+ export { useForm, useAsync, runAsync, type UseFormOptions, type UseFormReturn, type FieldError, type FormState, type InferFormData, type UseAsyncOptions, type UseAsyncReturn, } from './composables/index.js';
65
+ export * from './schemas/index.js';
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Classic Theme Svelte Components
3
+ *
4
+ * A collection of accessible, composable Svelte 5 components built on Bits UI
5
+ * and styled with Tailwind CSS using the Classic theme design tokens.
6
+ *
7
+ * All components use Svelte 5 runes syntax ($props, $state, $derived, etc.)
8
+ */
9
+ // Core UI Components
10
+ export { default as Button } from './components/Button.svelte';
11
+ export { default as Input } from './components/Input.svelte';
12
+ export { default as Label } from './components/Label.svelte';
13
+ export { default as Textarea } from './components/Textarea.svelte';
14
+ export { default as Checkbox } from './components/Checkbox.svelte';
15
+ export { default as Switch } from './components/Switch.svelte';
16
+ export { default as Separator } from './components/Separator.svelte';
17
+ // Card Components
18
+ export { default as Card } from './components/Card.svelte';
19
+ export { default as CardHeader } from './components/CardHeader.svelte';
20
+ export { default as CardTitle } from './components/CardTitle.svelte';
21
+ export { default as CardDescription } from './components/CardDescription.svelte';
22
+ export { default as CardContent } from './components/CardContent.svelte';
23
+ export { default as CardFooter } from './components/CardFooter.svelte';
24
+ // Alert Components
25
+ export { default as Alert } from './components/Alert.svelte';
26
+ export { default as AlertTitle } from './components/AlertTitle.svelte';
27
+ export { default as AlertDescription } from './components/AlertDescription.svelte';
28
+ // Badge
29
+ export { default as Badge } from './components/Badge.svelte';
30
+ // Feedback Components
31
+ export { default as Spinner } from './components/Spinner.svelte';
32
+ export { default as Skeleton } from './components/Skeleton.svelte';
33
+ export { default as Toast } from './components/Toast.svelte';
34
+ export { default as ToastContainer } from './components/ToastContainer.svelte';
35
+ // Overlay Components (using Bits UI)
36
+ export { default as Dialog } from './components/Dialog.svelte';
37
+ export { default as AlertDialog } from './components/AlertDialog.svelte';
38
+ export { default as Tooltip } from './components/Tooltip.svelte';
39
+ export { default as DropdownMenu } from './components/DropdownMenu.svelte';
40
+ // Form Components (using Bits UI)
41
+ export { default as Select } from './components/Select.svelte';
42
+ export { default as FormField } from './components/FormField.svelte';
43
+ export { default as FileUpload } from './components/FileUpload.svelte';
44
+ // Data Display
45
+ export { default as DataTable } from './components/DataTable.svelte';
46
+ // Tabs
47
+ export { default as Tabs } from './components/Tabs.svelte';
48
+ export { default as TabPanel } from './components/TabPanel.svelte';
49
+ // Branding
50
+ export { default as LogoMain } from './components/LogoMain.svelte';
51
+ export { default as LoadingLogo } from './components/LoadingLogo.svelte';
52
+ // Avatar Components
53
+ export { default as Avatar } from './components/Avatar.svelte';
54
+ export { default as AvatarImage } from './components/AvatarImage.svelte';
55
+ export { default as AvatarFallback } from './components/AvatarFallback.svelte';
56
+ // Page Components
57
+ export { default as Section } from './components/Section.svelte';
58
+ export { default as PageHeader } from './components/PageHeader.svelte';
59
+ // Layout Components
60
+ export { default as AppShell } from './components/layout/AppShell.svelte';
61
+ export { default as DashboardLayout } from './components/layout/DashboardLayout.svelte';
62
+ export { default as PublicLayout } from './components/layout/PublicLayout.svelte';
63
+ export { default as FormPageLayout } from './components/layout/FormPageLayout.svelte';
64
+ export { default as Sidebar } from './components/layout/Sidebar.svelte';
65
+ export { default as Header } from './components/layout/Header.svelte';
66
+ export { default as Footer } from './components/layout/Footer.svelte';
67
+ export { default as QuickLinks } from './components/layout/QuickLinks.svelte';
68
+ // Stores
69
+ export { toastStore } from './stores/toast.svelte.js';
70
+ export { sidebarStore } from './stores/sidebar.svelte.js';
71
+ export { themeStore } from './stores/theme.svelte.js';
72
+ // Utilities
73
+ export { cn } from './utils.js';
74
+ // Re-export tailwind-variants types for consumer convenience
75
+ export { tv } from 'tailwind-variants';
76
+ // Validation utilities (dev-only, tree-shaken in production)
77
+ export { validateNonEmptyArray, validateRequired, validateOneOf, validateRange, validateProps, createValidator, } from './validation.js';
78
+ // Performance monitoring utilities (dev-only, tree-shaken in production)
79
+ export { perfStart, perfEnd, measure, measureAsync, getPerformanceEntries, clearPerformanceEntries, createPerfMonitor, } from './performance.js';
80
+ // Composables - reusable Svelte 5 state management patterns
81
+ export { useForm, useAsync, runAsync, } from './composables/index.js';
82
+ // Validation schemas - Zod schemas for forms and data validation
83
+ export * from './schemas/index.js';
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Performance monitoring utilities for development
3
+ *
4
+ * All functions are no-ops in production builds for zero runtime cost.
5
+ * These utilities help identify slow operations during development.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { measure, measureAsync } from '@classic-homes/theme-svelte';
10
+ *
11
+ * // Sync measurement
12
+ * const result = measure('sort-data', () => {
13
+ * return data.sort((a, b) => a.name.localeCompare(b.name));
14
+ * });
15
+ *
16
+ * // Async measurement
17
+ * const data = await measureAsync('fetch-users', async () => {
18
+ * return await fetch('/api/users').then(r => r.json());
19
+ * });
20
+ * ```
21
+ */
22
+ export interface PerformanceMark {
23
+ name: string;
24
+ startTime: number;
25
+ duration?: number;
26
+ }
27
+ /**
28
+ * Start a performance measurement
29
+ * @param name - Unique name for this measurement
30
+ */
31
+ export declare function perfStart(name: string): void;
32
+ /**
33
+ * End a performance measurement and log results
34
+ * @param name - Name of the measurement to end
35
+ * @returns Duration in milliseconds, or undefined if not in dev mode
36
+ */
37
+ export declare function perfEnd(name: string): number | undefined;
38
+ /**
39
+ * Measure a synchronous function's execution time
40
+ * @param name - Name for the measurement
41
+ * @param fn - Function to measure
42
+ * @returns The function's return value
43
+ */
44
+ export declare function measure<T>(name: string, fn: () => T): T;
45
+ /**
46
+ * Measure an async function's execution time
47
+ * @param name - Name for the measurement
48
+ * @param fn - Async function to measure
49
+ * @returns Promise resolving to the function's return value
50
+ */
51
+ export declare function measureAsync<T>(name: string, fn: () => Promise<T>): Promise<T>;
52
+ /**
53
+ * Get all recorded performance measurements
54
+ * Useful for testing or building custom performance dashboards
55
+ * @returns Array of performance entries
56
+ */
57
+ export declare function getPerformanceEntries(): PerformanceEntryList;
58
+ /**
59
+ * Clear all recorded performance measurements
60
+ */
61
+ export declare function clearPerformanceEntries(): void;
62
+ /**
63
+ * Create a performance monitor for a specific component or module
64
+ * @param prefix - Prefix for all measurements (e.g., 'DataTable')
65
+ * @returns Object with prefixed measurement functions
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * const perf = createPerfMonitor('DataTable');
70
+ * perf.measure('sort', () => sortData());
71
+ * await perf.measureAsync('fetch', () => fetchData());
72
+ * ```
73
+ */
74
+ export declare function createPerfMonitor(prefix: string): {
75
+ start: (name: string) => void;
76
+ end: (name: string) => number | undefined;
77
+ measure: <T>(name: string, fn: () => T) => T;
78
+ measureAsync: <T>(name: string, fn: () => Promise<T>) => Promise<T>;
79
+ };
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Performance monitoring utilities for development
3
+ *
4
+ * All functions are no-ops in production builds for zero runtime cost.
5
+ * These utilities help identify slow operations during development.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { measure, measureAsync } from '@classic-homes/theme-svelte';
10
+ *
11
+ * // Sync measurement
12
+ * const result = measure('sort-data', () => {
13
+ * return data.sort((a, b) => a.name.localeCompare(b.name));
14
+ * });
15
+ *
16
+ * // Async measurement
17
+ * const data = await measureAsync('fetch-users', async () => {
18
+ * return await fetch('/api/users').then(r => r.json());
19
+ * });
20
+ * ```
21
+ */
22
+ // Detect development mode
23
+ const getIsDev = () => {
24
+ try {
25
+ // @ts-expect-error - import.meta.env may not exist
26
+ if (typeof import.meta !== 'undefined' && import.meta.env?.DEV !== undefined) {
27
+ // @ts-expect-error - accessing env.DEV
28
+ return import.meta.env.DEV === true;
29
+ }
30
+ }
31
+ catch {
32
+ // Ignore
33
+ }
34
+ try {
35
+ // @ts-expect-error - process may not exist
36
+ if (typeof process !== 'undefined' && process.env?.NODE_ENV !== undefined) {
37
+ // @ts-expect-error - accessing process.env
38
+ return process.env.NODE_ENV !== 'production';
39
+ }
40
+ }
41
+ catch {
42
+ // Ignore
43
+ }
44
+ return false;
45
+ };
46
+ const isDev = getIsDev();
47
+ const marks = new Map();
48
+ /** Threshold in ms for logging slow operations (1 frame at 60fps) */
49
+ const SLOW_THRESHOLD = 16;
50
+ /**
51
+ * Start a performance measurement
52
+ * @param name - Unique name for this measurement
53
+ */
54
+ export function perfStart(name) {
55
+ if (!isDev)
56
+ return;
57
+ marks.set(name, {
58
+ name,
59
+ startTime: performance.now(),
60
+ });
61
+ if (typeof performance !== 'undefined' && performance.mark) {
62
+ performance.mark(`${name}-start`);
63
+ }
64
+ }
65
+ /**
66
+ * End a performance measurement and log results
67
+ * @param name - Name of the measurement to end
68
+ * @returns Duration in milliseconds, or undefined if not in dev mode
69
+ */
70
+ export function perfEnd(name) {
71
+ if (!isDev)
72
+ return undefined;
73
+ const mark = marks.get(name);
74
+ if (!mark) {
75
+ console.warn(`[perf] No start mark found for "${name}"`);
76
+ return undefined;
77
+ }
78
+ const duration = performance.now() - mark.startTime;
79
+ mark.duration = duration;
80
+ if (typeof performance !== 'undefined' && performance.mark && performance.measure) {
81
+ performance.mark(`${name}-end`);
82
+ performance.measure(name, `${name}-start`, `${name}-end`);
83
+ }
84
+ // Log slow operations
85
+ if (duration > SLOW_THRESHOLD) {
86
+ console.warn(`[perf] Slow operation "${name}": ${duration.toFixed(2)}ms`);
87
+ }
88
+ else {
89
+ console.debug(`[perf] "${name}": ${duration.toFixed(2)}ms`);
90
+ }
91
+ marks.delete(name);
92
+ return duration;
93
+ }
94
+ /**
95
+ * Measure a synchronous function's execution time
96
+ * @param name - Name for the measurement
97
+ * @param fn - Function to measure
98
+ * @returns The function's return value
99
+ */
100
+ export function measure(name, fn) {
101
+ if (!isDev)
102
+ return fn();
103
+ perfStart(name);
104
+ try {
105
+ return fn();
106
+ }
107
+ finally {
108
+ perfEnd(name);
109
+ }
110
+ }
111
+ /**
112
+ * Measure an async function's execution time
113
+ * @param name - Name for the measurement
114
+ * @param fn - Async function to measure
115
+ * @returns Promise resolving to the function's return value
116
+ */
117
+ export async function measureAsync(name, fn) {
118
+ if (!isDev)
119
+ return fn();
120
+ perfStart(name);
121
+ try {
122
+ return await fn();
123
+ }
124
+ finally {
125
+ perfEnd(name);
126
+ }
127
+ }
128
+ /**
129
+ * Get all recorded performance measurements
130
+ * Useful for testing or building custom performance dashboards
131
+ * @returns Array of performance entries
132
+ */
133
+ export function getPerformanceEntries() {
134
+ if (typeof performance === 'undefined' || !performance.getEntriesByType) {
135
+ return [];
136
+ }
137
+ return performance.getEntriesByType('measure');
138
+ }
139
+ /**
140
+ * Clear all recorded performance measurements
141
+ */
142
+ export function clearPerformanceEntries() {
143
+ if (typeof performance === 'undefined')
144
+ return;
145
+ if (performance.clearMarks)
146
+ performance.clearMarks();
147
+ if (performance.clearMeasures)
148
+ performance.clearMeasures();
149
+ marks.clear();
150
+ }
151
+ /**
152
+ * Create a performance monitor for a specific component or module
153
+ * @param prefix - Prefix for all measurements (e.g., 'DataTable')
154
+ * @returns Object with prefixed measurement functions
155
+ *
156
+ * @example
157
+ * ```ts
158
+ * const perf = createPerfMonitor('DataTable');
159
+ * perf.measure('sort', () => sortData());
160
+ * await perf.measureAsync('fetch', () => fetchData());
161
+ * ```
162
+ */
163
+ export function createPerfMonitor(prefix) {
164
+ return {
165
+ start: (name) => perfStart(`${prefix}:${name}`),
166
+ end: (name) => perfEnd(`${prefix}:${name}`),
167
+ measure: (name, fn) => measure(`${prefix}:${name}`, fn),
168
+ measureAsync: (name, fn) => measureAsync(`${prefix}:${name}`, fn),
169
+ };
170
+ }