flikkui 0.2.0-beta.2 → 0.2.0-beta.5
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/README.md +92 -0
- package/dist/components/ai/PromptInput/PromptInput.js +23 -15
- package/dist/components/ai/PromptSuggestions/PromptSuggestion.d.ts +27 -0
- package/dist/components/ai/PromptSuggestions/PromptSuggestion.js +62 -0
- package/dist/components/ai/PromptSuggestions/PromptSuggestion.theme.d.ts +10 -0
- package/dist/components/ai/PromptSuggestions/PromptSuggestion.theme.js +12 -0
- package/dist/components/ai/PromptSuggestions/PromptSuggestion.types.d.ts +53 -0
- package/dist/components/ai/PromptSuggestions/index.d.ts +4 -2
- package/dist/components/ai/index.d.ts +2 -12
- package/dist/components/charts/ActivityRings/ActivityRings.js +70 -58
- package/dist/components/charts/ActivityRings/ActivityRings.theme.js +0 -1
- package/dist/components/charts/ActivityRings/ActivityRings.types.d.ts +17 -0
- package/dist/components/charts/BarChart/BarChart.js +8 -4
- package/dist/components/charts/BarChart/BarChart.types.d.ts +14 -0
- package/dist/components/charts/DonutChart/DonutChart.js +11 -8
- package/dist/components/charts/DonutChart/DonutChart.theme.d.ts +3 -0
- package/dist/components/charts/DonutChart/DonutChart.theme.js +5 -4
- package/dist/components/charts/DonutChart/donut-utils.d.ts +5 -0
- package/dist/components/charts/DonutChart/donut-utils.js +26 -1
- package/dist/components/charts/Heatmap/Heatmap.theme.js +2 -2
- package/dist/components/charts/shared/ChartAxis/XAxis.d.ts +2 -2
- package/dist/components/charts/shared/ChartAxis/XAxis.js +4 -4
- package/dist/components/charts/shared/ChartAxis/YAxis.d.ts +2 -2
- package/dist/components/charts/shared/ChartAxis/YAxis.js +8 -7
- package/dist/components/charts/shared/ChartGrid/HorizontalGrid.d.ts +1 -1
- package/dist/components/charts/shared/ChartGrid/HorizontalGrid.js +2 -2
- package/dist/components/charts/theme/chart.theme.d.ts +1 -1
- package/dist/components/charts/theme/chart.theme.js +39 -39
- package/dist/components/core/Accordion/Accordion.d.ts +1 -1
- package/dist/components/core/Accordion/Accordion.js +2 -2
- package/dist/components/core/Accordion/Accordion.types.d.ts +8 -0
- package/dist/components/core/Badge/Badge.js +11 -15
- package/dist/components/core/Badge/Badge.theme.js +7 -21
- package/dist/components/core/Badge/Badge.types.d.ts +9 -1
- package/dist/components/core/Button/Button.js +2 -2
- package/dist/components/core/Button/Button.theme.js +1 -1
- package/dist/components/core/Button/Button.types.d.ts +8 -0
- package/dist/components/core/Card/Card.js +8 -2
- package/dist/components/core/Card/Card.theme.js +1 -1
- package/dist/components/core/Card/Card.types.d.ts +24 -1
- package/dist/components/core/Drawer/Drawer.d.ts +1 -1
- package/dist/components/core/Drawer/Drawer.js +10 -40
- package/dist/components/core/Drawer/Drawer.theme.js +2 -1
- package/dist/components/core/Drawer/Drawer.types.d.ts +8 -0
- package/dist/components/core/Dropdown/Dropdown.d.ts +1 -1
- package/dist/components/core/Dropdown/Dropdown.js +2 -2
- package/dist/components/core/Dropdown/Dropdown.types.d.ts +8 -0
- package/dist/components/core/Metric/Metric.d.ts +1 -1
- package/dist/components/core/Metric/Metric.js +9 -5
- package/dist/components/core/Metric/Metric.theme.d.ts +1 -1
- package/dist/components/core/Metric/Metric.theme.js +38 -28
- package/dist/components/core/Metric/Metric.types.d.ts +27 -8
- package/dist/components/core/Modal/Modal.d.ts +1 -1
- package/dist/components/core/Modal/Modal.js +17 -40
- package/dist/components/core/Modal/Modal.theme.js +8 -3
- package/dist/components/core/Modal/Modal.types.d.ts +18 -0
- package/dist/components/core/Modal/index.d.ts +1 -1
- package/dist/components/core/Notification/Notification.js +2 -0
- package/dist/components/core/Pill/Pill.d.ts +6 -11
- package/dist/components/core/Pill/Pill.theme.d.ts +2 -2
- package/dist/components/core/Pill/Pill.types.d.ts +9 -22
- package/dist/components/core/Pill/index.d.ts +1 -1
- package/dist/components/core/Popover/Popover.d.ts +1 -1
- package/dist/components/core/Popover/Popover.js +2 -2
- package/dist/components/core/Popover/Popover.types.d.ts +8 -0
- package/dist/components/core/Progress/Progress.d.ts +28 -0
- package/dist/components/core/Progress/Progress.js +114 -0
- package/dist/components/core/Progress/Progress.theme.d.ts +5 -0
- package/dist/components/core/Progress/Progress.theme.js +33 -0
- package/dist/components/core/Progress/Progress.types.d.ts +92 -0
- package/dist/components/core/Progress/index.d.ts +2 -0
- package/dist/components/core/Table/Table.animations.d.ts +5 -16
- package/dist/components/core/Table/Table.animations.js +46 -0
- package/dist/components/core/Table/Table.d.ts +0 -27
- package/dist/components/core/Table/Table.js +58 -156
- package/dist/components/core/Table/Table.theme.js +28 -19
- package/dist/components/core/Table/Table.types.d.ts +95 -8
- package/dist/components/core/Table/Table.utils.d.ts +7 -0
- package/dist/components/core/Table/Table.utils.js +11 -1
- package/dist/components/core/Table/{components/TableActions/TableActions.d.ts → TableActions.d.ts} +3 -3
- package/dist/components/core/Table/{components/TableActions/TableActions.js → TableActions.js} +14 -24
- package/dist/components/core/Table/{components/TableActions/TableActionsMenu.d.ts → TableActionsMenu.d.ts} +1 -1
- package/dist/components/core/Table/{components/TableActions/TableActionsMenu.js → TableActionsMenu.js} +4 -4
- package/dist/components/core/Table/{components/core/TableBody.d.ts → TableBody.d.ts} +1 -1
- package/dist/components/core/Table/{components/core/TableBody.js → TableBody.js} +14 -20
- package/dist/components/core/Table/{components/core/TableCell.d.ts → TableCell.d.ts} +1 -9
- package/dist/components/core/Table/{components/core/TableCell.js → TableCell.js} +5 -13
- package/dist/components/core/Table/TableColumnManager.d.ts +3 -0
- package/dist/components/core/Table/TableColumnManager.js +34 -0
- package/dist/components/core/Table/{components/DeclarativeComponents.d.ts → TableDeclarative.d.ts} +1 -1
- package/dist/components/core/Table/{components/DeclarativeComponents.js → TableDeclarative.js} +6 -56
- package/dist/components/core/Table/TableFilter.d.ts +3 -0
- package/dist/components/core/Table/TableFilter.js +122 -0
- package/dist/components/core/Table/{components/core/TableHeader.d.ts → TableHeader.d.ts} +1 -1
- package/dist/components/core/Table/{components/core/TableHeader.js → TableHeader.js} +15 -29
- package/dist/components/core/Table/TablePagination.d.ts +7 -0
- package/dist/components/core/Table/{components/TablePagination/TablePagination.js → TablePagination.js} +5 -16
- package/dist/components/core/Table/TableRow.d.ts +8 -0
- package/dist/components/core/Table/TableRow.js +45 -0
- package/dist/components/core/Table/TableSelectionHeader.d.ts +7 -0
- package/dist/components/core/Table/{components/TableSelectionHeader/TableSelectionHeader.js → TableSelectionHeader.js} +4 -5
- package/dist/components/core/Table/hooks/index.d.ts +10 -0
- package/dist/components/core/Table/hooks/useTableColumns.d.ts +16 -0
- package/dist/components/core/Table/hooks/useTableColumns.js +67 -0
- package/dist/components/core/Table/hooks/useTableExpansion.d.ts +8 -0
- package/dist/components/core/Table/hooks/useTableExpansion.js +15 -0
- package/dist/components/core/Table/hooks/useTableFilter.d.ts +12 -0
- package/dist/components/core/Table/hooks/useTableFilter.js +37 -0
- package/dist/components/core/Table/hooks/useTablePagination.d.ts +12 -0
- package/dist/components/core/Table/hooks/useTablePagination.js +13 -0
- package/dist/components/core/Table/hooks/useTableSelection.d.ts +17 -0
- package/dist/components/core/Table/hooks/useTableSelection.js +40 -0
- package/dist/components/core/Table/index.d.ts +9 -8
- package/dist/components/core/Table/index.js +7 -5
- package/dist/components/core/Tabs/Tabs.js +2 -2
- package/dist/components/core/Tabs/Tabs.types.d.ts +8 -0
- package/dist/components/core/Tag/Tag.animations.d.ts +3 -0
- package/dist/components/core/Tag/Tag.animations.js +31 -0
- package/dist/components/core/Tag/Tag.d.ts +14 -0
- package/dist/components/core/Tag/Tag.js +45 -0
- package/dist/components/core/Tag/Tag.theme.d.ts +2 -0
- package/dist/components/core/Tag/Tag.theme.js +21 -0
- package/dist/components/core/Tag/Tag.types.d.ts +40 -0
- package/dist/components/core/Tag/index.d.ts +3 -0
- package/dist/components/core/Tooltip/Tooltip.d.ts +1 -1
- package/dist/components/core/Tooltip/Tooltip.js +3 -3
- package/dist/components/core/Tooltip/Tooltip.theme.js +1 -1
- package/dist/components/core/Tooltip/Tooltip.types.d.ts +17 -0
- package/dist/components/core/index.d.ts +2 -1
- package/dist/components/core/index.js +12 -5
- package/dist/components/effects/CustomCursor/CustomCursor.d.ts +0 -13
- package/dist/components/effects/CustomCursor/CustomCursor.js +26 -2
- package/dist/components/effects/CustomCursor/CustomCursor.theme.js +12 -1
- package/dist/components/effects/CustomCursor/CustomCursor.types.d.ts +14 -1
- package/dist/components/forms/Combobox/Combobox.d.ts +25 -0
- package/dist/components/forms/Combobox/Combobox.js +412 -0
- package/dist/components/forms/Combobox/Combobox.theme.d.ts +6 -0
- package/dist/components/forms/Combobox/Combobox.theme.js +60 -0
- package/dist/components/forms/Combobox/Combobox.types.d.ts +111 -0
- package/dist/components/forms/Combobox/index.d.ts +3 -0
- package/dist/components/forms/FileUpload/FileUpload.js +2 -0
- package/dist/components/forms/Input/Input.js +25 -28
- package/dist/components/forms/Input/inputMasks.d.ts +15 -0
- package/dist/components/forms/Input/inputMasks.js +72 -1
- package/dist/components/forms/InputTag/InputTag.d.ts +40 -0
- package/dist/components/forms/InputTag/InputTag.js +491 -0
- package/dist/components/forms/InputTag/InputTag.theme.d.ts +2 -0
- package/dist/components/forms/InputTag/InputTag.theme.js +16 -0
- package/dist/components/forms/InputTag/InputTag.types.d.ts +107 -0
- package/dist/components/forms/InputTag/index.d.ts +3 -0
- package/dist/components/forms/Select/Select.d.ts +101 -2
- package/dist/components/forms/Select/Select.js +128 -132
- package/dist/components/forms/Select/Select.theme.js +10 -14
- package/dist/components/forms/Select/Select.types.d.ts +6 -2
- package/dist/components/forms/Select/index.d.ts +7 -4
- package/dist/components/forms/Select/useSelectState.d.ts +66 -0
- package/dist/components/forms/Select/useSelectState.js +134 -0
- package/dist/components/forms/SelectExpand/SelectExpand.animations.d.ts +20 -0
- package/dist/components/forms/SelectExpand/SelectExpand.animations.js +74 -0
- package/dist/components/forms/SelectExpand/SelectExpand.d.ts +9 -0
- package/dist/components/forms/SelectExpand/SelectExpand.js +223 -0
- package/dist/components/forms/SelectExpand/SelectExpand.theme.d.ts +5 -0
- package/dist/components/forms/SelectExpand/SelectExpand.theme.js +74 -0
- package/dist/components/forms/SelectExpand/SelectExpand.types.d.ts +126 -0
- package/dist/components/forms/SelectExpand/index.d.ts +4 -0
- package/dist/components/forms/Switch/Switch.js +3 -3
- package/dist/components/forms/Switch/Switch.theme.d.ts +1 -1
- package/dist/components/forms/Switch/Switch.theme.js +2 -2
- package/dist/components/forms/TimePicker/TimePicker.animations.d.ts +0 -46
- package/dist/components/forms/TimePicker/TimePicker.d.ts +15 -6
- package/dist/components/forms/TimePicker/TimePicker.js +285 -124
- package/dist/components/forms/TimePicker/TimePicker.theme.d.ts +1 -1
- package/dist/components/forms/TimePicker/TimePicker.theme.js +39 -22
- package/dist/components/forms/TimePicker/TimePicker.types.d.ts +88 -34
- package/dist/components/forms/TimePicker/TimePickerContent.d.ts +7 -10
- package/dist/components/forms/TimePicker/TimePickerContent.js +149 -16
- package/dist/components/forms/TimePicker/TimePickerTrigger.d.ts +3 -3
- package/dist/components/forms/TimePicker/TimePickerTrigger.js +22 -19
- package/dist/components/forms/TimePicker/WheelColumn.d.ts +14 -0
- package/dist/components/forms/TimePicker/WheelColumn.js +90 -0
- package/dist/components/forms/TimePicker/index.d.ts +4 -1
- package/dist/components/forms/TimePicker/useWheelPicker.d.ts +37 -0
- package/dist/components/forms/TimePicker/useWheelPicker.js +138 -0
- package/dist/components/forms/forms.theme.d.ts +14 -0
- package/dist/components/forms/forms.theme.js +31 -0
- package/dist/components/forms/index.d.ts +9 -3
- package/dist/components/forms/index.js +73 -2
- package/dist/hooks/index.d.ts +0 -4
- package/dist/icons/Icon.d.ts +7 -0
- package/dist/icons/Icon.js +6 -2
- package/dist/index.js +21 -19
- package/dist/styles.css +1 -1
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/optimisticErrors.js +1 -70
- package/package.json +1 -1
- package/dist/components/ai/EditingIndicator/EditingIndicator.animations.d.ts +0 -31
- package/dist/components/ai/EditingIndicator/EditingIndicator.animations.js +0 -115
- package/dist/components/ai/EditingIndicator/EditingIndicator.d.ts +0 -35
- package/dist/components/ai/EditingIndicator/EditingIndicator.js +0 -94
- package/dist/components/ai/EditingIndicator/EditingIndicator.theme.d.ts +0 -2
- package/dist/components/ai/EditingIndicator/EditingIndicator.theme.js +0 -13
- package/dist/components/ai/EditingIndicator/EditingIndicator.types.d.ts +0 -54
- package/dist/components/ai/EditingIndicator/index.d.ts +0 -9
- package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.d.ts +0 -3
- package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.js +0 -126
- package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.theme.d.ts +0 -2
- package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.theme.js +0 -8
- package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.types.d.ts +0 -45
- package/dist/components/ai/GenerativeRenderer/index.d.ts +0 -3
- package/dist/components/ai/PresenceIndicator/PresenceIndicator.animations.d.ts +0 -17
- package/dist/components/ai/PresenceIndicator/PresenceIndicator.animations.js +0 -56
- package/dist/components/ai/PresenceIndicator/PresenceIndicator.d.ts +0 -38
- package/dist/components/ai/PresenceIndicator/PresenceIndicator.js +0 -110
- package/dist/components/ai/PresenceIndicator/PresenceIndicator.theme.d.ts +0 -2
- package/dist/components/ai/PresenceIndicator/PresenceIndicator.theme.js +0 -13
- package/dist/components/ai/PresenceIndicator/PresenceIndicator.types.d.ts +0 -53
- package/dist/components/ai/PresenceIndicator/index.d.ts +0 -8
- package/dist/components/ai/PresenceProvider/PresenceContext.d.ts +0 -24
- package/dist/components/ai/PresenceProvider/PresenceContext.js +0 -34
- package/dist/components/ai/PresenceProvider/PresenceProvider.d.ts +0 -32
- package/dist/components/ai/PresenceProvider/PresenceProvider.js +0 -321
- package/dist/components/ai/PresenceProvider/PresenceProvider.types.d.ts +0 -140
- package/dist/components/ai/PresenceProvider/adapters/MockAdapter.d.ts +0 -102
- package/dist/components/ai/PresenceProvider/adapters/MockAdapter.js +0 -331
- package/dist/components/ai/PresenceProvider/adapters/PresenceAdapter.d.ts +0 -93
- package/dist/components/ai/PresenceProvider/adapters/SupabaseAdapter.d.ts +0 -134
- package/dist/components/ai/PresenceProvider/adapters/WebSocketAdapter.d.ts +0 -149
- package/dist/components/ai/PresenceProvider/adapters/index.d.ts +0 -11
- package/dist/components/ai/PresenceProvider/index.d.ts +0 -10
- package/dist/components/ai/PromptSuggestions/PromptSuggestions.d.ts +0 -27
- package/dist/components/ai/PromptSuggestions/PromptSuggestions.js +0 -61
- package/dist/components/ai/PromptSuggestions/PromptSuggestions.types.d.ts +0 -65
- package/dist/components/ai/VersionSlider/VersionSlider.d.ts +0 -3
- package/dist/components/ai/VersionSlider/VersionSlider.js +0 -97
- package/dist/components/ai/VersionSlider/VersionSlider.theme.d.ts +0 -2
- package/dist/components/ai/VersionSlider/VersionSlider.theme.js +0 -18
- package/dist/components/ai/VersionSlider/VersionSlider.types.d.ts +0 -77
- package/dist/components/ai/VersionSlider/index.d.ts +0 -3
- package/dist/components/core/Pill/Pill.animations.js +0 -25
- package/dist/components/core/Pill/Pill.js +0 -145
- package/dist/components/core/Pill/Pill.theme.js +0 -65
- package/dist/components/core/RetryBoundary/RetryBoundary.d.ts +0 -35
- package/dist/components/core/RetryBoundary/RetryBoundary.js +0 -154
- package/dist/components/core/RetryBoundary/RetryBoundary.theme.d.ts +0 -2
- package/dist/components/core/RetryBoundary/RetryBoundary.theme.js +0 -7
- package/dist/components/core/RetryBoundary/RetryBoundary.types.d.ts +0 -51
- package/dist/components/core/RetryBoundary/index.d.ts +0 -3
- package/dist/components/core/Table/components/TableActions/TableActions.types.d.ts +0 -40
- package/dist/components/core/Table/components/TableActions/index.d.ts +0 -3
- package/dist/components/core/Table/components/TableActionsMenu.d.ts +0 -6
- package/dist/components/core/Table/components/TablePagination/TablePagination.d.ts +0 -17
- package/dist/components/core/Table/components/TablePagination/TablePagination.types.d.ts +0 -21
- package/dist/components/core/Table/components/TablePagination/index.d.ts +0 -2
- package/dist/components/core/Table/components/TableSelectionHeader/TableSelectionHeader.d.ts +0 -15
- package/dist/components/core/Table/components/TableSelectionHeader/index.d.ts +0 -3
- package/dist/components/core/Table/components/core/TableRow.d.ts +0 -3
- package/dist/components/core/Table/components/core/TableRow.js +0 -44
- package/dist/components/core/Table/components/core/index.d.ts +0 -4
- package/dist/components/forms/OptimisticForm/OptimisticForm.d.ts +0 -33
- package/dist/components/forms/OptimisticForm/OptimisticForm.js +0 -87
- package/dist/components/forms/OptimisticForm/OptimisticForm.theme.d.ts +0 -2
- package/dist/components/forms/OptimisticForm/OptimisticForm.theme.js +0 -8
- package/dist/components/forms/OptimisticForm/OptimisticForm.types.d.ts +0 -74
- package/dist/components/forms/OptimisticForm/index.d.ts +0 -3
- package/dist/hooks/useOptimisticMutation.d.ts +0 -109
- package/dist/hooks/useOptimisticMutation.js +0 -171
- package/dist/hooks/usePresence.d.ts +0 -88
- package/dist/utils/presenceUtils.d.ts +0 -66
- package/dist/utils/presenceUtils.js +0 -107
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useOptimisticMutation Hook
|
|
3
|
-
* Provides instant UI updates with automatic rollback on error
|
|
4
|
-
*/
|
|
5
|
-
import { OptimisticError } from "../utils/optimisticErrors";
|
|
6
|
-
import { type RetryConfig } from "../utils/retryUtils";
|
|
7
|
-
import { type ActionQueue, type AddActionOptions } from "../utils/actionQueue";
|
|
8
|
-
/**
|
|
9
|
-
* Mutation state
|
|
10
|
-
*/
|
|
11
|
-
export type MutationStatus = "idle" | "pending" | "success" | "error";
|
|
12
|
-
/**
|
|
13
|
-
* Options for useOptimisticMutation hook
|
|
14
|
-
*/
|
|
15
|
-
export interface OptimisticMutationOptions<TData, TVariables, TContext = unknown> {
|
|
16
|
-
/**
|
|
17
|
-
* Called before mutation - return context for rollback
|
|
18
|
-
* Context is passed to onSuccess, onError, and onSettled
|
|
19
|
-
*/
|
|
20
|
-
onMutate?: (variables: TVariables) => TContext | Promise<TContext>;
|
|
21
|
-
/**
|
|
22
|
-
* Apply optimistic update immediately
|
|
23
|
-
* Called synchronously before the mutation starts
|
|
24
|
-
*/
|
|
25
|
-
onOptimisticUpdate?: (variables: TVariables, context: TContext) => void;
|
|
26
|
-
/**
|
|
27
|
-
* Called on success - replace optimistic data with real data
|
|
28
|
-
*/
|
|
29
|
-
onSuccess?: (data: TData, variables: TVariables, context: TContext) => void;
|
|
30
|
-
/**
|
|
31
|
-
* Called on error - rollback optimistic update
|
|
32
|
-
* Use context to restore previous state
|
|
33
|
-
*/
|
|
34
|
-
onError?: (error: OptimisticError, variables: TVariables, context: TContext) => void;
|
|
35
|
-
/**
|
|
36
|
-
* Called after success or error (cleanup)
|
|
37
|
-
*/
|
|
38
|
-
onSettled?: (data: TData | undefined, error: OptimisticError | null, variables: TVariables, context: TContext) => void;
|
|
39
|
-
/**
|
|
40
|
-
* Retry configuration for failed mutations
|
|
41
|
-
*/
|
|
42
|
-
retry?: RetryConfig;
|
|
43
|
-
/**
|
|
44
|
-
* Queue mutation when offline instead of failing immediately
|
|
45
|
-
*/
|
|
46
|
-
offlineQueue?: boolean;
|
|
47
|
-
/**
|
|
48
|
-
* Custom action queue instance (defaults to global queue)
|
|
49
|
-
*/
|
|
50
|
-
actionQueue?: ActionQueue;
|
|
51
|
-
/**
|
|
52
|
-
* Options for queued action (label, description)
|
|
53
|
-
*/
|
|
54
|
-
queueOptions?: Omit<AddActionOptions, "maxRetries">;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Return value from useOptimisticMutation hook
|
|
58
|
-
*/
|
|
59
|
-
export interface OptimisticMutationReturn<TData, TVariables> {
|
|
60
|
-
/** Trigger the mutation */
|
|
61
|
-
mutate: (variables: TVariables) => void;
|
|
62
|
-
/** Trigger the mutation and return a Promise */
|
|
63
|
-
mutateAsync: (variables: TVariables) => Promise<TData>;
|
|
64
|
-
/** Response data from the last successful mutation */
|
|
65
|
-
data: TData | undefined;
|
|
66
|
-
/** Error from the last failed mutation */
|
|
67
|
-
error: OptimisticError | null;
|
|
68
|
-
/** Current mutation status */
|
|
69
|
-
status: MutationStatus;
|
|
70
|
-
/** True when no mutation is in progress or completed */
|
|
71
|
-
isIdle: boolean;
|
|
72
|
-
/** True when mutation is in progress */
|
|
73
|
-
isPending: boolean;
|
|
74
|
-
/** True when showing optimistic data (mutation in progress) */
|
|
75
|
-
isOptimistic: boolean;
|
|
76
|
-
/** True when mutation completed successfully */
|
|
77
|
-
isSuccess: boolean;
|
|
78
|
-
/** True when mutation failed */
|
|
79
|
-
isError: boolean;
|
|
80
|
-
/** True when error occurred and rollback was applied */
|
|
81
|
-
isRolledBack: boolean;
|
|
82
|
-
/** True when mutation was queued for offline processing */
|
|
83
|
-
isQueued: boolean;
|
|
84
|
-
/** Reset the mutation state */
|
|
85
|
-
reset: () => void;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Hook for optimistic UI mutations with automatic rollback
|
|
89
|
-
*
|
|
90
|
-
* @example
|
|
91
|
-
* const { mutate, isOptimistic, isPending } = useOptimisticMutation(
|
|
92
|
-
* async (data) => api.createMessage(data),
|
|
93
|
-
* {
|
|
94
|
-
* onOptimisticUpdate: (newMessage) => {
|
|
95
|
-
* setMessages(prev => [...prev, { ...newMessage, id: 'temp-id', isPending: true }]);
|
|
96
|
-
* },
|
|
97
|
-
* onSuccess: (response) => {
|
|
98
|
-
* setMessages(prev => prev.map(m =>
|
|
99
|
-
* m.id === 'temp-id' ? { ...response, isPending: false } : m
|
|
100
|
-
* ));
|
|
101
|
-
* },
|
|
102
|
-
* onError: (error) => {
|
|
103
|
-
* setMessages(prev => prev.filter(m => m.id !== 'temp-id'));
|
|
104
|
-
* toast.error('Failed to send message');
|
|
105
|
-
* }
|
|
106
|
-
* }
|
|
107
|
-
* );
|
|
108
|
-
*/
|
|
109
|
-
export declare function useOptimisticMutation<TData, TVariables, TContext = unknown>(mutationFn: (variables: TVariables) => Promise<TData>, options?: OptimisticMutationOptions<TData, TVariables, TContext>): OptimisticMutationReturn<TData, TVariables>;
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { useState, useRef, useCallback } from 'react';
|
|
2
|
-
import { normalizeOptimisticError, MutationError } from '../utils/optimisticErrors.js';
|
|
3
|
-
import { shouldRetry, calculateRetryDelay } from '../utils/retryUtils.js';
|
|
4
|
-
import { useNetworkStatus } from './useNetworkStatus.js';
|
|
5
|
-
import { getDefaultQueue } from '../utils/actionQueue.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* useOptimisticMutation Hook
|
|
9
|
-
* Provides instant UI updates with automatic rollback on error
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
* Hook for optimistic UI mutations with automatic rollback
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* const { mutate, isOptimistic, isPending } = useOptimisticMutation(
|
|
16
|
-
* async (data) => api.createMessage(data),
|
|
17
|
-
* {
|
|
18
|
-
* onOptimisticUpdate: (newMessage) => {
|
|
19
|
-
* setMessages(prev => [...prev, { ...newMessage, id: 'temp-id', isPending: true }]);
|
|
20
|
-
* },
|
|
21
|
-
* onSuccess: (response) => {
|
|
22
|
-
* setMessages(prev => prev.map(m =>
|
|
23
|
-
* m.id === 'temp-id' ? { ...response, isPending: false } : m
|
|
24
|
-
* ));
|
|
25
|
-
* },
|
|
26
|
-
* onError: (error) => {
|
|
27
|
-
* setMessages(prev => prev.filter(m => m.id !== 'temp-id'));
|
|
28
|
-
* toast.error('Failed to send message');
|
|
29
|
-
* }
|
|
30
|
-
* }
|
|
31
|
-
* );
|
|
32
|
-
*/
|
|
33
|
-
function useOptimisticMutation(mutationFn, options = {}) {
|
|
34
|
-
var _a;
|
|
35
|
-
const [status, setStatus] = useState("idle");
|
|
36
|
-
const [data, setData] = useState(undefined);
|
|
37
|
-
const [error, setError] = useState(null);
|
|
38
|
-
const [isRolledBack, setIsRolledBack] = useState(false);
|
|
39
|
-
const [isQueued, setIsQueued] = useState(false);
|
|
40
|
-
// Track if we're showing optimistic data
|
|
41
|
-
const isOptimisticRef = useRef(false);
|
|
42
|
-
const [isOptimistic, setIsOptimistic] = useState(false);
|
|
43
|
-
// Get network status for offline queueing
|
|
44
|
-
const { isOnline } = useNetworkStatus();
|
|
45
|
-
// Get action queue
|
|
46
|
-
const actionQueue = (_a = options.actionQueue) !== null && _a !== void 0 ? _a : getDefaultQueue();
|
|
47
|
-
/**
|
|
48
|
-
* Reset mutation state
|
|
49
|
-
*/
|
|
50
|
-
const reset = useCallback(() => {
|
|
51
|
-
setStatus("idle");
|
|
52
|
-
setData(undefined);
|
|
53
|
-
setError(null);
|
|
54
|
-
setIsRolledBack(false);
|
|
55
|
-
setIsQueued(false);
|
|
56
|
-
setIsOptimistic(false);
|
|
57
|
-
isOptimisticRef.current = false;
|
|
58
|
-
}, []);
|
|
59
|
-
/**
|
|
60
|
-
* Execute mutation with retry logic
|
|
61
|
-
*/
|
|
62
|
-
const executeMutation = useCallback(async (variables, context, attempt = 0) => {
|
|
63
|
-
try {
|
|
64
|
-
const result = await mutationFn(variables);
|
|
65
|
-
return result;
|
|
66
|
-
}
|
|
67
|
-
catch (err) {
|
|
68
|
-
const optimisticError = normalizeOptimisticError(err, {
|
|
69
|
-
originalData: variables,
|
|
70
|
-
});
|
|
71
|
-
// Check if we should retry
|
|
72
|
-
if (options.retry &&
|
|
73
|
-
shouldRetry(optimisticError, attempt, options.retry)) {
|
|
74
|
-
const delay = calculateRetryDelay(attempt, options.retry);
|
|
75
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
76
|
-
return executeMutation(variables, context, attempt + 1);
|
|
77
|
-
}
|
|
78
|
-
throw optimisticError;
|
|
79
|
-
}
|
|
80
|
-
}, [mutationFn, options.retry]);
|
|
81
|
-
/**
|
|
82
|
-
* Core mutation logic
|
|
83
|
-
*/
|
|
84
|
-
const mutateAsync = useCallback(async (variables) => {
|
|
85
|
-
var _a, _b, _c, _d, _e, _f;
|
|
86
|
-
// Handle offline queueing
|
|
87
|
-
if (!isOnline && options.offlineQueue) {
|
|
88
|
-
const queueId = actionQueue.add(() => mutationFn(variables), {
|
|
89
|
-
maxRetries: (_a = options.retry) === null || _a === void 0 ? void 0 : _a.maxAttempts,
|
|
90
|
-
...options.queueOptions,
|
|
91
|
-
});
|
|
92
|
-
setIsQueued(true);
|
|
93
|
-
setStatus("pending");
|
|
94
|
-
// Return a rejected promise with queue info
|
|
95
|
-
throw new MutationError(`Mutation queued for offline processing (ID: ${queueId})`, true, // Will be retried when online
|
|
96
|
-
variables);
|
|
97
|
-
}
|
|
98
|
-
// Reset previous state
|
|
99
|
-
setError(null);
|
|
100
|
-
setIsRolledBack(false);
|
|
101
|
-
setIsQueued(false);
|
|
102
|
-
setStatus("pending");
|
|
103
|
-
// Get context from onMutate
|
|
104
|
-
let context;
|
|
105
|
-
try {
|
|
106
|
-
context = (await ((_b = options.onMutate) === null || _b === void 0 ? void 0 : _b.call(options, variables)));
|
|
107
|
-
}
|
|
108
|
-
catch (err) {
|
|
109
|
-
// onMutate failed - don't proceed
|
|
110
|
-
const mutateError = normalizeOptimisticError(err);
|
|
111
|
-
setError(mutateError);
|
|
112
|
-
setStatus("error");
|
|
113
|
-
throw mutateError;
|
|
114
|
-
}
|
|
115
|
-
// Apply optimistic update
|
|
116
|
-
if (options.onOptimisticUpdate) {
|
|
117
|
-
isOptimisticRef.current = true;
|
|
118
|
-
setIsOptimistic(true);
|
|
119
|
-
options.onOptimisticUpdate(variables, context);
|
|
120
|
-
}
|
|
121
|
-
try {
|
|
122
|
-
// Execute the mutation
|
|
123
|
-
const result = await executeMutation(variables, context);
|
|
124
|
-
// Success - replace optimistic data
|
|
125
|
-
isOptimisticRef.current = false;
|
|
126
|
-
setIsOptimistic(false);
|
|
127
|
-
setData(result);
|
|
128
|
-
setStatus("success");
|
|
129
|
-
(_c = options.onSuccess) === null || _c === void 0 ? void 0 : _c.call(options, result, variables, context);
|
|
130
|
-
(_d = options.onSettled) === null || _d === void 0 ? void 0 : _d.call(options, result, null, variables, context);
|
|
131
|
-
return result;
|
|
132
|
-
}
|
|
133
|
-
catch (err) {
|
|
134
|
-
// Error - rollback optimistic update
|
|
135
|
-
const optimisticError = err instanceof MutationError ? err : normalizeOptimisticError(err);
|
|
136
|
-
isOptimisticRef.current = false;
|
|
137
|
-
setIsOptimistic(false);
|
|
138
|
-
setError(optimisticError);
|
|
139
|
-
setStatus("error");
|
|
140
|
-
setIsRolledBack(true);
|
|
141
|
-
(_e = options.onError) === null || _e === void 0 ? void 0 : _e.call(options, optimisticError, variables, context);
|
|
142
|
-
(_f = options.onSettled) === null || _f === void 0 ? void 0 : _f.call(options, undefined, optimisticError, variables, context);
|
|
143
|
-
throw optimisticError;
|
|
144
|
-
}
|
|
145
|
-
}, [isOnline, options, actionQueue, mutationFn, executeMutation]);
|
|
146
|
-
/**
|
|
147
|
-
* Fire-and-forget mutation
|
|
148
|
-
*/
|
|
149
|
-
const mutate = useCallback((variables) => {
|
|
150
|
-
mutateAsync(variables).catch(() => {
|
|
151
|
-
// Error already handled in mutateAsync
|
|
152
|
-
});
|
|
153
|
-
}, [mutateAsync]);
|
|
154
|
-
return {
|
|
155
|
-
mutate,
|
|
156
|
-
mutateAsync,
|
|
157
|
-
data,
|
|
158
|
-
error,
|
|
159
|
-
status,
|
|
160
|
-
isIdle: status === "idle",
|
|
161
|
-
isPending: status === "pending",
|
|
162
|
-
isOptimistic,
|
|
163
|
-
isSuccess: status === "success",
|
|
164
|
-
isError: status === "error",
|
|
165
|
-
isRolledBack,
|
|
166
|
-
isQueued,
|
|
167
|
-
reset,
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
export { useOptimisticMutation };
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* usePresence Hook
|
|
3
|
-
*
|
|
4
|
-
* Custom hook for accessing presence state and controls.
|
|
5
|
-
* Wraps usePresenceContext with additional features like filtering.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```tsx
|
|
9
|
-
* function CustomPresenceUI() {
|
|
10
|
-
* const { users, typingUsers, isConnected, startTyping } = usePresence();
|
|
11
|
-
*
|
|
12
|
-
* return (
|
|
13
|
-
* <div>
|
|
14
|
-
* <h2>{users.length} users online</h2>
|
|
15
|
-
* {typingUsers.length > 0 && <p>Someone is typing...</p>}
|
|
16
|
-
* </div>
|
|
17
|
-
* );
|
|
18
|
-
* }
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
import { PresenceUser, TypingUser, ConnectionStatus } from "../components/ai/PresenceProvider/PresenceProvider.types";
|
|
22
|
-
/**
|
|
23
|
-
* Options for usePresence hook
|
|
24
|
-
*/
|
|
25
|
-
export interface UsePresenceOptions {
|
|
26
|
-
/** Filter users */
|
|
27
|
-
filter?: (user: PresenceUser) => boolean;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Return value from usePresence hook
|
|
31
|
-
*/
|
|
32
|
-
export interface UsePresenceReturn {
|
|
33
|
-
/** All users in channel (filtered if filter provided) */
|
|
34
|
-
users: PresenceUser[];
|
|
35
|
-
/** All users (unfiltered) */
|
|
36
|
-
allUsers: PresenceUser[];
|
|
37
|
-
/** Users currently typing */
|
|
38
|
-
typingUsers: TypingUser[];
|
|
39
|
-
/** Current user data */
|
|
40
|
-
currentUser: PresenceUser;
|
|
41
|
-
/** Current connection status */
|
|
42
|
-
connectionStatus: ConnectionStatus;
|
|
43
|
-
/** Is actively connected */
|
|
44
|
-
isConnected: boolean;
|
|
45
|
-
/** Is connecting or reconnecting */
|
|
46
|
-
isConnecting: boolean;
|
|
47
|
-
/** Connection error (if any) */
|
|
48
|
-
error: Error | null;
|
|
49
|
-
/** Manually connect to channel */
|
|
50
|
-
connect: () => Promise<void>;
|
|
51
|
-
/** Manually disconnect from channel */
|
|
52
|
-
disconnect: () => Promise<void>;
|
|
53
|
-
/** Start typing indicator */
|
|
54
|
-
startTyping: () => void;
|
|
55
|
-
/** Stop typing indicator */
|
|
56
|
-
stopTyping: () => void;
|
|
57
|
-
/** Update current user metadata */
|
|
58
|
-
updateUser: (updates: Partial<PresenceUser>) => void;
|
|
59
|
-
/** Send custom presence event */
|
|
60
|
-
sendEvent: (event: string, data?: unknown) => void;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Hook for accessing presence state and controls
|
|
64
|
-
*
|
|
65
|
-
* @param options - Hook options (filtering, etc.)
|
|
66
|
-
* @returns Presence state and control functions
|
|
67
|
-
*
|
|
68
|
-
* @throws Error if used outside PresenceProvider
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```tsx
|
|
72
|
-
* // Basic usage
|
|
73
|
-
* const { users, isConnected } = usePresence();
|
|
74
|
-
*
|
|
75
|
-
* // With filtering (online users only)
|
|
76
|
-
* const { users } = usePresence({
|
|
77
|
-
* filter: (user) => user.status === 'online',
|
|
78
|
-
* });
|
|
79
|
-
*
|
|
80
|
-
* // Typing controls
|
|
81
|
-
* const { startTyping, stopTyping } = usePresence();
|
|
82
|
-
* const handleInputChange = () => {
|
|
83
|
-
* startTyping();
|
|
84
|
-
* setTimeout(stopTyping, 3000);
|
|
85
|
-
* };
|
|
86
|
-
* ```
|
|
87
|
-
*/
|
|
88
|
-
export declare function usePresence(options?: UsePresenceOptions): UsePresenceReturn;
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Presence Utilities
|
|
3
|
-
*
|
|
4
|
-
* Helper functions for formatting presence and typing indicators.
|
|
5
|
-
*/
|
|
6
|
-
import { PresenceUser, TypingUser } from "../components/ai/PresenceProvider/PresenceProvider.types";
|
|
7
|
-
/**
|
|
8
|
-
* Format typing users into human-readable text
|
|
9
|
-
*
|
|
10
|
-
* @param users - Array of users currently typing
|
|
11
|
-
* @param maxVisible - Maximum users to show by name (default: 3)
|
|
12
|
-
* @returns Formatted text like "Alice is typing..." or "3 people are typing..."
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* formatTypingText([{ id: '1', name: 'Alice' }]) // "Alice is typing..."
|
|
16
|
-
* formatTypingText([{ id: '1', name: 'Alice' }, { id: '2', name: 'Bob' }]) // "Alice and Bob are typing..."
|
|
17
|
-
* formatTypingText([...4 users...]) // "Alice, Bob, Charlie, and 1 other are typing..."
|
|
18
|
-
*/
|
|
19
|
-
export declare function formatTypingText(users: TypingUser[], maxVisible?: number): string;
|
|
20
|
-
/**
|
|
21
|
-
* Format presence count into human-readable text
|
|
22
|
-
*
|
|
23
|
-
* @param count - Number of users online
|
|
24
|
-
* @returns Formatted text like "5 users online" or "1 user online"
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* formatPresenceCount(1) // "1 user online"
|
|
28
|
-
* formatPresenceCount(5) // "5 users online"
|
|
29
|
-
*/
|
|
30
|
-
export declare function formatPresenceCount(count: number): string;
|
|
31
|
-
/**
|
|
32
|
-
* Validate presence user data
|
|
33
|
-
* Type guard to ensure object conforms to PresenceUser interface
|
|
34
|
-
*
|
|
35
|
-
* @param user - Unknown object to validate
|
|
36
|
-
* @returns True if valid PresenceUser
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* const data = await fetchUserData();
|
|
40
|
-
* if (validatePresenceUser(data)) {
|
|
41
|
-
* // TypeScript knows data is PresenceUser
|
|
42
|
-
* console.log(data.name);
|
|
43
|
-
* }
|
|
44
|
-
*/
|
|
45
|
-
export declare function validatePresenceUser(user: unknown): user is PresenceUser;
|
|
46
|
-
/**
|
|
47
|
-
* Validate typing user data
|
|
48
|
-
* Type guard to ensure object conforms to TypingUser interface
|
|
49
|
-
*
|
|
50
|
-
* @param user - Unknown object to validate
|
|
51
|
-
* @returns True if valid TypingUser
|
|
52
|
-
*/
|
|
53
|
-
export declare function validateTypingUser(user: unknown): user is TypingUser;
|
|
54
|
-
/**
|
|
55
|
-
* Sort presence users by various criteria
|
|
56
|
-
*
|
|
57
|
-
* @param users - Array of users to sort
|
|
58
|
-
* @param sortBy - Sort criteria or custom comparator
|
|
59
|
-
* @returns Sorted array (does not mutate original)
|
|
60
|
-
*
|
|
61
|
-
* @example
|
|
62
|
-
* sortUsers(users, 'name') // Sort alphabetically by name
|
|
63
|
-
* sortUsers(users, 'joinedAt') // Sort by join time (newest first)
|
|
64
|
-
* sortUsers(users, (a, b) => a.metadata.score - b.metadata.score) // Custom sort
|
|
65
|
-
*/
|
|
66
|
-
export declare function sortUsers(users: PresenceUser[], sortBy: "name" | "joinedAt" | "status" | ((a: PresenceUser, b: PresenceUser) => number)): PresenceUser[];
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Presence Utilities
|
|
3
|
-
*
|
|
4
|
-
* Helper functions for formatting presence and typing indicators.
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Format typing users into human-readable text
|
|
8
|
-
*
|
|
9
|
-
* @param users - Array of users currently typing
|
|
10
|
-
* @param maxVisible - Maximum users to show by name (default: 3)
|
|
11
|
-
* @returns Formatted text like "Alice is typing..." or "3 people are typing..."
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* formatTypingText([{ id: '1', name: 'Alice' }]) // "Alice is typing..."
|
|
15
|
-
* formatTypingText([{ id: '1', name: 'Alice' }, { id: '2', name: 'Bob' }]) // "Alice and Bob are typing..."
|
|
16
|
-
* formatTypingText([...4 users...]) // "Alice, Bob, Charlie, and 1 other are typing..."
|
|
17
|
-
*/
|
|
18
|
-
function formatTypingText(users, maxVisible = 3) {
|
|
19
|
-
const count = users.length;
|
|
20
|
-
if (count === 0) {
|
|
21
|
-
return "";
|
|
22
|
-
}
|
|
23
|
-
if (count === 1) {
|
|
24
|
-
return `${users[0].name} is typing...`;
|
|
25
|
-
}
|
|
26
|
-
if (count === 2) {
|
|
27
|
-
return `${users[0].name} and ${users[1].name} are typing...`;
|
|
28
|
-
}
|
|
29
|
-
// 3 or more users
|
|
30
|
-
if (count <= maxVisible) {
|
|
31
|
-
const names = users
|
|
32
|
-
.slice(0, count - 1)
|
|
33
|
-
.map((u) => u.name)
|
|
34
|
-
.join(", ");
|
|
35
|
-
const lastName = users[count - 1].name;
|
|
36
|
-
return `${names}, and ${lastName} are typing...`;
|
|
37
|
-
}
|
|
38
|
-
// More than maxVisible users
|
|
39
|
-
const visibleNames = users
|
|
40
|
-
.slice(0, maxVisible)
|
|
41
|
-
.map((u) => u.name)
|
|
42
|
-
.join(", ");
|
|
43
|
-
const remaining = count - maxVisible;
|
|
44
|
-
return `${visibleNames}, and ${remaining} ${remaining === 1 ? "other" : "others"} are typing...`;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Format presence count into human-readable text
|
|
48
|
-
*
|
|
49
|
-
* @param count - Number of users online
|
|
50
|
-
* @returns Formatted text like "5 users online" or "1 user online"
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* formatPresenceCount(1) // "1 user online"
|
|
54
|
-
* formatPresenceCount(5) // "5 users online"
|
|
55
|
-
*/
|
|
56
|
-
function formatPresenceCount(count) {
|
|
57
|
-
if (count === 0) {
|
|
58
|
-
return "No users online";
|
|
59
|
-
}
|
|
60
|
-
if (count === 1) {
|
|
61
|
-
return "1 user online";
|
|
62
|
-
}
|
|
63
|
-
return `${count} users online`;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Sort presence users by various criteria
|
|
67
|
-
*
|
|
68
|
-
* @param users - Array of users to sort
|
|
69
|
-
* @param sortBy - Sort criteria or custom comparator
|
|
70
|
-
* @returns Sorted array (does not mutate original)
|
|
71
|
-
*
|
|
72
|
-
* @example
|
|
73
|
-
* sortUsers(users, 'name') // Sort alphabetically by name
|
|
74
|
-
* sortUsers(users, 'joinedAt') // Sort by join time (newest first)
|
|
75
|
-
* sortUsers(users, (a, b) => a.metadata.score - b.metadata.score) // Custom sort
|
|
76
|
-
*/
|
|
77
|
-
function sortUsers(users, sortBy) {
|
|
78
|
-
const sorted = [...users]; // Don't mutate original
|
|
79
|
-
if (typeof sortBy === "function") {
|
|
80
|
-
return sorted.sort(sortBy);
|
|
81
|
-
}
|
|
82
|
-
switch (sortBy) {
|
|
83
|
-
case "name":
|
|
84
|
-
return sorted.sort((a, b) => a.name.localeCompare(b.name));
|
|
85
|
-
case "joinedAt":
|
|
86
|
-
return sorted.sort((a, b) => {
|
|
87
|
-
var _a, _b, _c, _d;
|
|
88
|
-
const aTime = (_b = (_a = a.joinedAt) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0;
|
|
89
|
-
const bTime = (_d = (_c = b.joinedAt) === null || _c === void 0 ? void 0 : _c.getTime()) !== null && _d !== void 0 ? _d : 0;
|
|
90
|
-
return bTime - aTime; // Newest first
|
|
91
|
-
});
|
|
92
|
-
case "status": {
|
|
93
|
-
// Order: online > busy > away > offline
|
|
94
|
-
const statusOrder = { online: 0, busy: 1, away: 2, offline: 3 };
|
|
95
|
-
return sorted.sort((a, b) => {
|
|
96
|
-
var _a, _b;
|
|
97
|
-
const aOrder = statusOrder[(_a = a.status) !== null && _a !== void 0 ? _a : "offline"];
|
|
98
|
-
const bOrder = statusOrder[(_b = b.status) !== null && _b !== void 0 ? _b : "offline"];
|
|
99
|
-
return aOrder - bOrder;
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
default:
|
|
103
|
-
return sorted;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export { formatPresenceCount, formatTypingText, sortUsers };
|