@gram-ai/elements 1.27.4 → 1.27.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 +72 -60
- package/README.typedoc.md +6 -6
- package/bin/cli.js +74 -74
- package/dist/compat-shims-CO9JXXV4.cjs.map +1 -1
- package/dist/{compat-shims-BPJ7Q68c.js → compat-shims-DxtUrORi.js} +4 -2
- package/dist/compat-shims-DxtUrORi.js.map +1 -0
- package/dist/components/ShareButton/index.d.ts +2 -2
- package/dist/components/assistant-ui/message-feedback.d.ts +1 -1
- package/dist/components/assistant-ui/tooltip-icon-button.d.ts +2 -2
- package/dist/components/ui/avatar.d.ts +2 -2
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/calendar.d.ts +1 -1
- package/dist/components/ui/collapsible.d.ts +1 -1
- package/dist/components/ui/dialog.d.ts +4 -4
- package/dist/components/ui/popover.d.ts +2 -2
- package/dist/components/ui/skeleton.d.ts +1 -1
- package/dist/components/ui/time-range-picker.d.ts +1 -1
- package/dist/components/ui/tool-ui.d.ts +7 -7
- package/dist/components/ui/tooltip.d.ts +2 -2
- package/dist/contexts/ConnectionStatusContext.d.ts +1 -1
- package/dist/elements.cjs +1 -1
- package/dist/elements.js +2 -2
- package/dist/hooks/useDensity.d.ts +73 -73
- package/dist/hooks/useMCPTools.d.ts +1 -1
- package/dist/hooks/useRadius.d.ts +1 -1
- package/dist/{index-BpJstUh1.cjs → index-C4bFBGfl.cjs} +4 -4
- package/dist/{index-BpJstUh1.cjs.map → index-C4bFBGfl.cjs.map} +1 -1
- package/dist/{index-CUitXazZ.js → index-D93pV0_o.js} +55 -55
- package/dist/{index-CUitXazZ.js.map → index-D93pV0_o.js.map} +1 -1
- package/dist/{index-D0bAYNQy.js → index-DuCQRbcQ.js} +279 -265
- package/dist/index-DuCQRbcQ.js.map +1 -0
- package/dist/{index-KSX4Qjip.cjs → index-y_PNN5vK.cjs} +10 -10
- package/dist/index-y_PNN5vK.cjs.map +1 -0
- package/dist/lib/cassette.d.ts +4 -4
- package/dist/lib/errorTracking.d.ts +1 -1
- package/dist/lib/messageConverter.d.ts +1 -1
- package/dist/lib/models.d.ts +1 -1
- package/dist/plugins/chart/ui/bar-chart.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/accordion-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/accordion.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/action-button.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/alert-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/alert.d.ts +4 -4
- package/dist/plugins/generative-ui/ui/avatar.d.ts +5 -5
- package/dist/plugins/generative-ui/ui/badge.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/button-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/button.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/card-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/card.d.ts +8 -8
- package/dist/plugins/generative-ui/ui/checkbox.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/data-table.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/dialog.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/dropdown-menu.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/grid.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/input-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/input.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/label.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/metric.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/pagination.d.ts +6 -6
- package/dist/plugins/generative-ui/ui/popover.d.ts +4 -4
- package/dist/plugins/generative-ui/ui/progress.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/radio-group.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/select.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/separator.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/skeleton.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/stack.d.ts +6 -6
- package/dist/plugins/generative-ui/ui/switch.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/table.d.ts +9 -9
- package/dist/plugins/generative-ui/ui/tabs-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/tabs.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/text.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/textarea.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/tooltip.d.ts +1 -1
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.js +1 -1
- package/dist/{profiler-BFkhZRxj.js → profiler-FpBY9eRv.js} +2 -2
- package/dist/{profiler-BFkhZRxj.js.map → profiler-FpBY9eRv.js.map} +1 -1
- package/dist/{profiler-CyzxBxVz.cjs → profiler-_mthyjvo.cjs} +2 -2
- package/dist/{profiler-CyzxBxVz.cjs.map → profiler-_mthyjvo.cjs.map} +1 -1
- package/dist/react-shim.js +1 -1
- package/dist/server/express.cjs.map +1 -1
- package/dist/server/express.js.map +1 -1
- package/dist/{startRecording-Dq92sEHf.cjs → startRecording-NJcpiHw-.cjs} +2 -2
- package/dist/{startRecording-Dq92sEHf.cjs.map → startRecording-NJcpiHw-.cjs.map} +1 -1
- package/dist/{startRecording-C-PPAs_Z.js → startRecording-r5MXQ2Dm.js} +2 -2
- package/dist/{startRecording-C-PPAs_Z.js.map → startRecording-r5MXQ2Dm.js.map} +1 -1
- package/dist/types/index.d.ts +2 -2
- package/package.json +1 -5
- package/src/compat-plugin.ts +14 -14
- package/src/compat-shims.ts +33 -31
- package/src/compat.test.ts +48 -48
- package/src/compat.ts +6 -6
- package/src/components/Chat/index.tsx +17 -17
- package/src/components/Chat/stories/Charts.stories.tsx +98 -98
- package/src/components/Chat/stories/Composer.stories.tsx +15 -15
- package/src/components/Chat/stories/ConnectionConfiguration.stories.tsx +44 -44
- package/src/components/Chat/stories/CustomComponents.stories.tsx +17 -17
- package/src/components/Chat/stories/Density.stories.tsx +20 -20
- package/src/components/Chat/stories/ErrorBoundary.stories.tsx +47 -47
- package/src/components/Chat/stories/FrontendTools.stories.tsx +39 -39
- package/src/components/Chat/stories/GenerativeUI.stories.tsx +48 -48
- package/src/components/Chat/stories/MessageFeedback.stories.tsx +52 -52
- package/src/components/Chat/stories/Modal.stories.tsx +28 -28
- package/src/components/Chat/stories/Model.stories.tsx +11 -11
- package/src/components/Chat/stories/Radius.stories.tsx +20 -20
- package/src/components/Chat/stories/Sidecar.stories.tsx +13 -13
- package/src/components/Chat/stories/StyleIsolation.stories.tsx +11 -11
- package/src/components/Chat/stories/Theme.stories.tsx +25 -25
- package/src/components/Chat/stories/Thread.stories.tsx +25 -25
- package/src/components/Chat/stories/ToolApproval.stories.tsx +55 -55
- package/src/components/Chat/stories/ToolMentions.stories.tsx +17 -17
- package/src/components/Chat/stories/Tools.stories.tsx +88 -88
- package/src/components/Chat/stories/Variants.stories.tsx +32 -32
- package/src/components/Chat/stories/Welcome.stories.tsx +14 -14
- package/src/components/ChatHistory.tsx +7 -7
- package/src/components/FrontendTools/index.tsx +5 -5
- package/src/components/Replay.stories.tsx +157 -157
- package/src/components/Replay.tsx +76 -73
- package/src/components/ShadowRoot.tsx +40 -40
- package/src/components/ShareButton/index.tsx +32 -32
- package/src/components/assistant-ui/assistant-modal.tsx +92 -87
- package/src/components/assistant-ui/assistant-sidecar.tsx +35 -35
- package/src/components/assistant-ui/attachment.tsx +80 -80
- package/src/components/assistant-ui/connection-status-indicator.tsx +33 -33
- package/src/components/assistant-ui/error-boundary.tsx +34 -34
- package/src/components/assistant-ui/follow-on-suggestions.tsx +26 -26
- package/src/components/assistant-ui/markdown-text.tsx +69 -69
- package/src/components/assistant-ui/mentioned-tools-badges.tsx +38 -38
- package/src/components/assistant-ui/message-feedback.tsx +57 -50
- package/src/components/assistant-ui/reasoning.tsx +83 -83
- package/src/components/assistant-ui/thread-list.tsx +45 -45
- package/src/components/assistant-ui/thread.tsx +278 -278
- package/src/components/assistant-ui/tool-fallback.tsx +37 -37
- package/src/components/assistant-ui/tool-group.tsx +26 -26
- package/src/components/assistant-ui/tool-mention-autocomplete.tsx +122 -122
- package/src/components/assistant-ui/tooltip-icon-button.tsx +18 -18
- package/src/components/ui/avatar.tsx +12 -12
- package/src/components/ui/button.tsx +12 -12
- package/src/components/ui/buttonVariants.ts +17 -17
- package/src/components/ui/calendar.tsx +106 -106
- package/src/components/ui/charts.stories.tsx +56 -56
- package/src/components/ui/collapsible.tsx +5 -5
- package/src/components/ui/dialog.tsx +30 -30
- package/src/components/ui/generative-ui.stories.tsx +200 -200
- package/src/components/ui/generative-ui.tsx +26 -26
- package/src/components/ui/popover.tsx +14 -14
- package/src/components/ui/skeleton.tsx +5 -5
- package/src/components/ui/time-range-picker.stories.tsx +80 -80
- package/src/components/ui/time-range-picker.tsx +245 -244
- package/src/components/ui/tool-ui.stories.tsx +37 -37
- package/src/components/ui/tool-ui.tsx +221 -215
- package/src/components/ui/tooltip.tsx +15 -15
- package/src/constants/tailwind.ts +1 -1
- package/src/contexts/ChatIdContext.tsx +7 -7
- package/src/contexts/ConnectionStatusContext.tsx +64 -64
- package/src/contexts/ElementsProvider.tsx +214 -213
- package/src/contexts/ReplayContext.ts +3 -3
- package/src/contexts/ToolApprovalContext.tsx +54 -54
- package/src/contexts/ToolExecutionContext.tsx +34 -34
- package/src/contexts/contexts.ts +7 -7
- package/src/contexts/portal-container-context.ts +2 -2
- package/src/contexts/portal-container.tsx +7 -7
- package/src/embedded.ts +1 -1
- package/src/global.css +25 -25
- package/src/hooks/useAuth.ts +72 -72
- package/src/hooks/useDensity.ts +79 -79
- package/src/hooks/useElements.ts +6 -6
- package/src/hooks/useExpanded.ts +12 -12
- package/src/hooks/useFollowOnSuggestions.ts +83 -83
- package/src/hooks/useGramThreadListAdapter.tsx +99 -99
- package/src/hooks/useMCPTools.ts +47 -47
- package/src/hooks/useModel.ts +14 -14
- package/src/hooks/usePluginComponents.ts +11 -11
- package/src/hooks/usePortalContainer.ts +5 -5
- package/src/hooks/useRadius.ts +23 -23
- package/src/hooks/useRecordCassette.ts +34 -34
- package/src/hooks/useSession.ts +11 -11
- package/src/hooks/useThemeProps.ts +13 -13
- package/src/hooks/useThreadId.ts +4 -4
- package/src/hooks/useToolApproval.ts +7 -7
- package/src/hooks/useToolMentions.ts +40 -40
- package/src/index.ts +26 -26
- package/src/lib/api.test.ts +61 -61
- package/src/lib/api.ts +4 -3
- package/src/lib/auth.ts +13 -13
- package/src/lib/cassette.ts +84 -84
- package/src/lib/easing.ts +1 -1
- package/src/lib/errorTracking.config.ts +5 -5
- package/src/lib/errorTracking.ts +29 -29
- package/src/lib/generative-ui.ts +7 -7
- package/src/lib/humanize.ts +3 -3
- package/src/lib/messageConverter.test.ts +130 -127
- package/src/lib/messageConverter.ts +196 -196
- package/src/lib/models.ts +21 -20
- package/src/lib/token.test.ts +56 -56
- package/src/lib/token.ts +14 -14
- package/src/lib/tool-mentions.ts +45 -45
- package/src/lib/tools.ts +66 -62
- package/src/lib/utils.ts +5 -5
- package/src/lib.d.ts +1 -1
- package/src/plugins/README.md +5 -5
- package/src/plugins/chart/catalog.ts +18 -18
- package/src/plugins/chart/chart.test.ts +31 -31
- package/src/plugins/chart/component.tsx +34 -34
- package/src/plugins/chart/index.ts +4 -4
- package/src/plugins/chart/ui/area-chart.tsx +42 -42
- package/src/plugins/chart/ui/bar-chart.tsx +46 -46
- package/src/plugins/chart/ui/donut-chart.tsx +48 -48
- package/src/plugins/chart/ui/index.ts +7 -7
- package/src/plugins/chart/ui/line-chart.tsx +43 -43
- package/src/plugins/chart/ui/pie-chart.tsx +44 -44
- package/src/plugins/chart/ui/radar-chart.tsx +33 -33
- package/src/plugins/chart/ui/scatter-chart.tsx +43 -43
- package/src/plugins/components/MacOSWindowFrame.tsx +15 -15
- package/src/plugins/components/PluginLoadingState.tsx +10 -10
- package/src/plugins/components/index.ts +1 -1
- package/src/plugins/generative-ui/catalog.ts +54 -54
- package/src/plugins/generative-ui/component.tsx +85 -85
- package/src/plugins/generative-ui/index.ts +4 -4
- package/src/plugins/generative-ui/ui/accordion-wrapper.tsx +16 -16
- package/src/plugins/generative-ui/ui/accordion.tsx +16 -16
- package/src/plugins/generative-ui/ui/action-button.tsx +28 -28
- package/src/plugins/generative-ui/ui/alert-wrapper.tsx +8 -8
- package/src/plugins/generative-ui/ui/alert.tsx +20 -20
- package/src/plugins/generative-ui/ui/avatar-wrapper.tsx +7 -7
- package/src/plugins/generative-ui/ui/avatar.tsx +30 -30
- package/src/plugins/generative-ui/ui/badge.tsx +22 -22
- package/src/plugins/generative-ui/ui/button-wrapper.tsx +12 -12
- package/src/plugins/generative-ui/ui/button.tsx +28 -28
- package/src/plugins/generative-ui/ui/card-wrapper.tsx +8 -8
- package/src/plugins/generative-ui/ui/card.tsx +27 -27
- package/src/plugins/generative-ui/ui/checkbox-wrapper.tsx +9 -9
- package/src/plugins/generative-ui/ui/checkbox.tsx +9 -9
- package/src/plugins/generative-ui/ui/data-table.tsx +8 -8
- package/src/plugins/generative-ui/ui/dialog.tsx +31 -31
- package/src/plugins/generative-ui/ui/dropdown-menu.tsx +44 -44
- package/src/plugins/generative-ui/ui/grid.tsx +12 -12
- package/src/plugins/generative-ui/ui/index.ts +40 -40
- package/src/plugins/generative-ui/ui/input-wrapper.tsx +11 -11
- package/src/plugins/generative-ui/ui/input.tsx +9 -9
- package/src/plugins/generative-ui/ui/label.tsx +8 -8
- package/src/plugins/generative-ui/ui/list.tsx +11 -11
- package/src/plugins/generative-ui/ui/metric.tsx +23 -23
- package/src/plugins/generative-ui/ui/pagination.tsx +28 -28
- package/src/plugins/generative-ui/ui/popover.tsx +21 -21
- package/src/plugins/generative-ui/ui/progress.tsx +13 -13
- package/src/plugins/generative-ui/ui/radio-group.tsx +12 -12
- package/src/plugins/generative-ui/ui/select-wrapper.tsx +7 -7
- package/src/plugins/generative-ui/ui/select.tsx +37 -37
- package/src/plugins/generative-ui/ui/separator.tsx +9 -9
- package/src/plugins/generative-ui/ui/skeleton-wrapper.tsx +10 -10
- package/src/plugins/generative-ui/ui/skeleton.tsx +5 -5
- package/src/plugins/generative-ui/ui/stack.tsx +28 -28
- package/src/plugins/generative-ui/ui/switch.tsx +11 -11
- package/src/plugins/generative-ui/ui/table.tsx +32 -32
- package/src/plugins/generative-ui/ui/tabs-wrapper.tsx +11 -11
- package/src/plugins/generative-ui/ui/tabs.tsx +26 -26
- package/src/plugins/generative-ui/ui/text.tsx +12 -12
- package/src/plugins/generative-ui/ui/textarea.tsx +7 -7
- package/src/plugins/generative-ui/ui/tooltip.tsx +12 -12
- package/src/plugins/index.ts +7 -7
- package/src/react-shim.ts +6 -6
- package/src/server/bun.ts +12 -12
- package/src/server/core.ts +25 -25
- package/src/server/express.ts +17 -15
- package/src/server/fastify.ts +14 -14
- package/src/server/hono.ts +9 -9
- package/src/server/nextjs.ts +12 -12
- package/src/server/tanstack-start.ts +12 -12
- package/src/server.ts +27 -27
- package/src/storybook.d.ts +4 -4
- package/src/types/index.ts +122 -122
- package/src/types/plugins.ts +7 -7
- package/src/vite-env.d.ts +12 -12
- package/dist/compat-shims-BPJ7Q68c.js.map +0 -1
- package/dist/index-D0bAYNQy.js.map +0 -1
- package/dist/index-KSX4Qjip.cjs.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import * as React from
|
|
4
|
-
import * as TooltipPrimitive from
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
5
5
|
|
|
6
|
-
import { cn } from
|
|
7
|
-
import { usePortalContainer } from
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
import { usePortalContainer } from "@/hooks/usePortalContainer";
|
|
8
8
|
|
|
9
9
|
function TooltipProvider({
|
|
10
10
|
delayDuration = 0,
|
|
@@ -16,7 +16,7 @@ function TooltipProvider({
|
|
|
16
16
|
delayDuration={delayDuration}
|
|
17
17
|
{...props}
|
|
18
18
|
/>
|
|
19
|
-
)
|
|
19
|
+
);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function Tooltip({
|
|
@@ -26,13 +26,13 @@ function Tooltip({
|
|
|
26
26
|
<TooltipProvider>
|
|
27
27
|
<TooltipPrimitive.Root data-slot="tooltip" {...props} />
|
|
28
28
|
</TooltipProvider>
|
|
29
|
-
)
|
|
29
|
+
);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function TooltipTrigger({
|
|
33
33
|
...props
|
|
34
34
|
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
|
|
35
|
-
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props}
|
|
35
|
+
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
function TooltipContent({
|
|
@@ -42,25 +42,25 @@ function TooltipContent({
|
|
|
42
42
|
container,
|
|
43
43
|
...props
|
|
44
44
|
}: React.ComponentProps<typeof TooltipPrimitive.Content> & {
|
|
45
|
-
container?: HTMLElement | null
|
|
45
|
+
container?: HTMLElement | null;
|
|
46
46
|
}) {
|
|
47
|
-
const portalContainer = usePortalContainer()
|
|
47
|
+
const portalContainer = usePortalContainer();
|
|
48
48
|
return (
|
|
49
49
|
<TooltipPrimitive.Portal container={container ?? portalContainer}>
|
|
50
50
|
<TooltipPrimitive.Content
|
|
51
51
|
data-slot="tooltip-content"
|
|
52
52
|
sideOffset={sideOffset}
|
|
53
53
|
className={cn(
|
|
54
|
-
|
|
55
|
-
className
|
|
54
|
+
"z-[70] w-fit origin-(--radix-tooltip-content-transform-origin) animate-in rounded-md bg-foreground px-3 py-1.5 text-xs text-balance text-background fade-in-0 zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
55
|
+
className,
|
|
56
56
|
)}
|
|
57
57
|
{...props}
|
|
58
58
|
>
|
|
59
59
|
{children}
|
|
60
|
-
<TooltipPrimitive.Arrow className="
|
|
60
|
+
<TooltipPrimitive.Arrow className="z-[70] size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" />
|
|
61
61
|
</TooltipPrimitive.Content>
|
|
62
62
|
</TooltipPrimitive.Portal>
|
|
63
|
-
)
|
|
63
|
+
);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
|
|
66
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Used to scope elements styles to the Elements library
|
|
2
|
-
export const ROOT_SELECTOR =
|
|
2
|
+
export const ROOT_SELECTOR = "gram-elements";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { createContext, useContext } from
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
2
|
|
|
3
3
|
export interface ChatIdContextValue {
|
|
4
|
-
chatId: string | null
|
|
4
|
+
chatId: string | null;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
export const ChatIdContext = createContext<ChatIdContextValue | null>(null)
|
|
7
|
+
export const ChatIdContext = createContext<ChatIdContextValue | null>(null);
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Hook to access the current chat ID from the Elements context.
|
|
@@ -13,9 +13,9 @@ export const ChatIdContext = createContext<ChatIdContextValue | null>(null)
|
|
|
13
13
|
* @returns The current chat ID, or null if not yet initialized
|
|
14
14
|
*/
|
|
15
15
|
export const useChatId = () => {
|
|
16
|
-
const context = useContext(ChatIdContext)
|
|
16
|
+
const context = useContext(ChatIdContext);
|
|
17
17
|
if (!context) {
|
|
18
|
-
throw new Error(
|
|
18
|
+
throw new Error("useChatId must be used within ElementsProvider");
|
|
19
19
|
}
|
|
20
|
-
return context.chatId
|
|
21
|
-
}
|
|
20
|
+
return context.chatId;
|
|
21
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
createContext,
|
|
@@ -8,119 +8,119 @@ import {
|
|
|
8
8
|
useRef,
|
|
9
9
|
useEffect,
|
|
10
10
|
type ReactNode,
|
|
11
|
-
} from
|
|
11
|
+
} from "react";
|
|
12
12
|
|
|
13
|
-
export type ConnectionState =
|
|
13
|
+
export type ConnectionState = "connected" | "reconnecting" | "disconnected";
|
|
14
14
|
|
|
15
15
|
interface ConnectionStatusContextValue {
|
|
16
16
|
/** Current connection state */
|
|
17
|
-
state: ConnectionState
|
|
17
|
+
state: ConnectionState;
|
|
18
18
|
/** Number of reconnection attempts */
|
|
19
|
-
retryCount: number
|
|
19
|
+
retryCount: number;
|
|
20
20
|
/** Whether the browser reports being online */
|
|
21
|
-
isOnline: boolean
|
|
21
|
+
isOnline: boolean;
|
|
22
22
|
/** Mark connection as failed - will trigger reconnecting state */
|
|
23
|
-
markDisconnected: () => void
|
|
23
|
+
markDisconnected: () => void;
|
|
24
24
|
/** Mark connection as restored */
|
|
25
|
-
markConnected: () => void
|
|
25
|
+
markConnected: () => void;
|
|
26
26
|
/** Reset the connection state */
|
|
27
|
-
reset: () => void
|
|
27
|
+
reset: () => void;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
const ConnectionStatusContext =
|
|
31
|
-
createContext<ConnectionStatusContextValue | null>(null)
|
|
31
|
+
createContext<ConnectionStatusContextValue | null>(null);
|
|
32
32
|
|
|
33
33
|
interface ConnectionStatusProviderProps {
|
|
34
|
-
children: ReactNode
|
|
34
|
+
children: ReactNode;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
export const ConnectionStatusProvider = ({
|
|
38
38
|
children,
|
|
39
39
|
}: ConnectionStatusProviderProps) => {
|
|
40
|
-
const [state, setState] = useState<ConnectionState>(
|
|
41
|
-
const [retryCount, setRetryCount] = useState(0)
|
|
40
|
+
const [state, setState] = useState<ConnectionState>("connected");
|
|
41
|
+
const [retryCount, setRetryCount] = useState(0);
|
|
42
42
|
const [isOnline, setIsOnline] = useState(
|
|
43
|
-
typeof navigator !==
|
|
44
|
-
)
|
|
45
|
-
const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null)
|
|
43
|
+
typeof navigator !== "undefined" ? navigator.onLine : true,
|
|
44
|
+
);
|
|
45
|
+
const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
46
46
|
|
|
47
47
|
// Monitor browser online/offline status
|
|
48
48
|
useEffect(() => {
|
|
49
|
-
if (typeof window ===
|
|
49
|
+
if (typeof window === "undefined") return;
|
|
50
50
|
|
|
51
51
|
const handleOnline = () => {
|
|
52
|
-
setIsOnline(true)
|
|
52
|
+
setIsOnline(true);
|
|
53
53
|
|
|
54
54
|
// Clear any existing timeout
|
|
55
55
|
if (reconnectTimeoutRef.current) {
|
|
56
|
-
clearTimeout(reconnectTimeoutRef.current)
|
|
57
|
-
reconnectTimeoutRef.current = null
|
|
56
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
57
|
+
reconnectTimeoutRef.current = null;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
// Show "Reconnecting..." briefly, then mark as connected
|
|
61
|
-
setState(
|
|
61
|
+
setState("reconnecting");
|
|
62
62
|
reconnectTimeoutRef.current = setTimeout(() => {
|
|
63
|
-
setState(
|
|
64
|
-
setRetryCount(0)
|
|
65
|
-
}, 1500) // Show reconnecting for 1.5s before clearing
|
|
66
|
-
}
|
|
63
|
+
setState("connected");
|
|
64
|
+
setRetryCount(0);
|
|
65
|
+
}, 1500); // Show reconnecting for 1.5s before clearing
|
|
66
|
+
};
|
|
67
67
|
|
|
68
68
|
const handleOffline = () => {
|
|
69
|
-
setIsOnline(false)
|
|
69
|
+
setIsOnline(false);
|
|
70
70
|
// Immediately mark as disconnected when browser goes offline
|
|
71
|
-
setState(
|
|
71
|
+
setState("disconnected");
|
|
72
72
|
if (reconnectTimeoutRef.current) {
|
|
73
|
-
clearTimeout(reconnectTimeoutRef.current)
|
|
74
|
-
reconnectTimeoutRef.current = null
|
|
73
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
74
|
+
reconnectTimeoutRef.current = null;
|
|
75
75
|
}
|
|
76
|
-
}
|
|
76
|
+
};
|
|
77
77
|
|
|
78
|
-
window.addEventListener(
|
|
79
|
-
window.addEventListener(
|
|
78
|
+
window.addEventListener("online", handleOnline);
|
|
79
|
+
window.addEventListener("offline", handleOffline);
|
|
80
80
|
|
|
81
81
|
return () => {
|
|
82
|
-
window.removeEventListener(
|
|
83
|
-
window.removeEventListener(
|
|
82
|
+
window.removeEventListener("online", handleOnline);
|
|
83
|
+
window.removeEventListener("offline", handleOffline);
|
|
84
84
|
// Clear any pending timeout to prevent memory leak
|
|
85
85
|
if (reconnectTimeoutRef.current) {
|
|
86
|
-
clearTimeout(reconnectTimeoutRef.current)
|
|
87
|
-
reconnectTimeoutRef.current = null
|
|
86
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
87
|
+
reconnectTimeoutRef.current = null;
|
|
88
88
|
}
|
|
89
|
-
}
|
|
90
|
-
}, [])
|
|
89
|
+
};
|
|
90
|
+
}, []);
|
|
91
91
|
|
|
92
92
|
const markDisconnected = useCallback(() => {
|
|
93
|
-
setState(
|
|
94
|
-
setRetryCount((prev) => prev + 1)
|
|
93
|
+
setState("reconnecting");
|
|
94
|
+
setRetryCount((prev) => prev + 1);
|
|
95
95
|
|
|
96
96
|
// After 10 seconds of reconnecting, mark as fully disconnected
|
|
97
97
|
if (reconnectTimeoutRef.current) {
|
|
98
|
-
clearTimeout(reconnectTimeoutRef.current)
|
|
98
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
99
99
|
}
|
|
100
100
|
reconnectTimeoutRef.current = setTimeout(() => {
|
|
101
101
|
setState((current) =>
|
|
102
|
-
current ===
|
|
103
|
-
)
|
|
104
|
-
}, 10000)
|
|
105
|
-
}, [])
|
|
102
|
+
current === "reconnecting" ? "disconnected" : current,
|
|
103
|
+
);
|
|
104
|
+
}, 10000);
|
|
105
|
+
}, []);
|
|
106
106
|
|
|
107
107
|
const markConnected = useCallback(() => {
|
|
108
108
|
if (reconnectTimeoutRef.current) {
|
|
109
|
-
clearTimeout(reconnectTimeoutRef.current)
|
|
110
|
-
reconnectTimeoutRef.current = null
|
|
109
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
110
|
+
reconnectTimeoutRef.current = null;
|
|
111
111
|
}
|
|
112
|
-
setState(
|
|
113
|
-
setRetryCount(0)
|
|
114
|
-
}, [])
|
|
112
|
+
setState("connected");
|
|
113
|
+
setRetryCount(0);
|
|
114
|
+
}, []);
|
|
115
115
|
|
|
116
116
|
const reset = useCallback(() => {
|
|
117
117
|
if (reconnectTimeoutRef.current) {
|
|
118
|
-
clearTimeout(reconnectTimeoutRef.current)
|
|
119
|
-
reconnectTimeoutRef.current = null
|
|
118
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
119
|
+
reconnectTimeoutRef.current = null;
|
|
120
120
|
}
|
|
121
|
-
setState(
|
|
122
|
-
setRetryCount(0)
|
|
123
|
-
}, [])
|
|
121
|
+
setState("connected");
|
|
122
|
+
setRetryCount(0);
|
|
123
|
+
}, []);
|
|
124
124
|
|
|
125
125
|
return (
|
|
126
126
|
<ConnectionStatusContext.Provider
|
|
@@ -135,18 +135,18 @@ export const ConnectionStatusProvider = ({
|
|
|
135
135
|
>
|
|
136
136
|
{children}
|
|
137
137
|
</ConnectionStatusContext.Provider>
|
|
138
|
-
)
|
|
139
|
-
}
|
|
138
|
+
);
|
|
139
|
+
};
|
|
140
140
|
|
|
141
141
|
export const useConnectionStatus = () => {
|
|
142
|
-
const context = useContext(ConnectionStatusContext)
|
|
142
|
+
const context = useContext(ConnectionStatusContext);
|
|
143
143
|
if (!context) {
|
|
144
144
|
throw new Error(
|
|
145
|
-
|
|
146
|
-
)
|
|
145
|
+
"useConnectionStatus must be used within a ConnectionStatusProvider",
|
|
146
|
+
);
|
|
147
147
|
}
|
|
148
|
-
return context
|
|
149
|
-
}
|
|
148
|
+
return context;
|
|
149
|
+
};
|
|
150
150
|
|
|
151
151
|
/**
|
|
152
152
|
* Hook that returns connection status helpers for use in sendMessages.
|
|
@@ -154,5 +154,5 @@ export const useConnectionStatus = () => {
|
|
|
154
154
|
*/
|
|
155
155
|
|
|
156
156
|
export const useConnectionStatusOptional = () => {
|
|
157
|
-
return useContext(ConnectionStatusContext)
|
|
158
|
-
}
|
|
157
|
+
return useContext(ConnectionStatusContext);
|
|
158
|
+
};
|