@djangocfg/centrifugo 1.0.5 → 1.0.7
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/package.json +4 -4
- package/src/components/CentrifugoMonitor/CentrifugoMonitorDialog.tsx +39 -29
- package/src/components/CentrifugoMonitor/CentrifugoMonitorFAB.tsx +23 -29
- package/src/components/CentrifugoMonitor/CentrifugoMonitorWidget.tsx +27 -39
- package/src/components/CentrifugoMonitor/index.ts +0 -1
- package/src/components/ConnectionStatus/ConnectionStatusCard.tsx +25 -29
- package/src/events.ts +44 -0
- package/src/index.ts +6 -0
- package/src/providers/CentrifugoProvider/CentrifugoProvider.tsx +10 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/centrifugo",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "Production-ready Centrifugo WebSocket client with React integration, RPC pattern, composable UI components, and comprehensive monitoring tools",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"centrifuge": "^5.2.2"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
|
-
"@djangocfg/ui": "^1.2.
|
|
23
|
-
"@djangocfg/layouts": "^1.2.
|
|
22
|
+
"@djangocfg/ui": "^1.2.32",
|
|
23
|
+
"@djangocfg/layouts": "^1.2.32",
|
|
24
24
|
"consola": "^3.4.2",
|
|
25
25
|
"lucide-react": "^0.468.0",
|
|
26
26
|
"moment": "^2.30.1",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"react-dom": "^19.0.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@djangocfg/typescript-config": "^1.2.
|
|
31
|
+
"@djangocfg/typescript-config": "^1.2.32",
|
|
32
32
|
"@types/react": "^19.0.6",
|
|
33
33
|
"@types/react-dom": "^19.0.2",
|
|
34
34
|
"moment": "^2.30.1",
|
|
@@ -2,63 +2,73 @@
|
|
|
2
2
|
* Centrifugo Monitor Dialog Component
|
|
3
3
|
*
|
|
4
4
|
* Sheet/Dialog wrapper for CentrifugoMonitor
|
|
5
|
+
* Uses event-driven approach - listens to OPEN_MONITOR_DIALOG event
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
'use client';
|
|
8
9
|
|
|
9
|
-
import React from 'react';
|
|
10
|
+
import React, { useState } from 'react';
|
|
10
11
|
import {
|
|
11
12
|
Sheet,
|
|
12
13
|
SheetContent,
|
|
13
14
|
SheetHeader,
|
|
14
15
|
SheetTitle,
|
|
15
16
|
SheetDescription,
|
|
17
|
+
useEventListener,
|
|
16
18
|
} from '@djangocfg/ui';
|
|
17
19
|
import { Activity } from 'lucide-react';
|
|
18
|
-
import { CentrifugoMonitor
|
|
20
|
+
import { CentrifugoMonitor } from './CentrifugoMonitor';
|
|
21
|
+
import { CENTRIFUGO_MONITOR_EVENTS, type OpenMonitorDialogPayload } from '../../events';
|
|
19
22
|
|
|
20
23
|
// ─────────────────────────────────────────────────────────────────────────
|
|
21
|
-
//
|
|
24
|
+
// Component
|
|
22
25
|
// ─────────────────────────────────────────────────────────────────────────
|
|
23
26
|
|
|
24
|
-
export
|
|
25
|
-
open
|
|
26
|
-
|
|
27
|
-
title?: string;
|
|
28
|
-
description?: string;
|
|
29
|
-
side?: 'left' | 'right' | 'top' | 'bottom';
|
|
30
|
-
className?: string;
|
|
31
|
-
}
|
|
27
|
+
export function CentrifugoMonitorDialog() {
|
|
28
|
+
const [open, setOpen] = useState(false);
|
|
29
|
+
const [variant, setVariant] = useState<'compact' | 'full' | 'minimal'>('full');
|
|
32
30
|
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
// Listen for dialog open event
|
|
32
|
+
useEventListener<typeof CENTRIFUGO_MONITOR_EVENTS.OPEN_MONITOR_DIALOG, OpenMonitorDialogPayload>(
|
|
33
|
+
CENTRIFUGO_MONITOR_EVENTS.OPEN_MONITOR_DIALOG,
|
|
34
|
+
(payload) => {
|
|
35
|
+
if (payload?.variant) {
|
|
36
|
+
setVariant(payload.variant);
|
|
37
|
+
}
|
|
38
|
+
setOpen(true);
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// Listen for dialog close event
|
|
43
|
+
useEventListener(
|
|
44
|
+
CENTRIFUGO_MONITOR_EVENTS.CLOSE_MONITOR_DIALOG,
|
|
45
|
+
() => {
|
|
46
|
+
setOpen(false);
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const handleClose = () => {
|
|
51
|
+
setOpen(false);
|
|
52
|
+
};
|
|
36
53
|
|
|
37
|
-
export function CentrifugoMonitorDialog({
|
|
38
|
-
open,
|
|
39
|
-
onOpenChange,
|
|
40
|
-
title = 'Centrifugo Monitor',
|
|
41
|
-
description = 'Real-time WebSocket monitoring and debugging',
|
|
42
|
-
side = 'right',
|
|
43
|
-
className = '',
|
|
44
|
-
...monitorProps
|
|
45
|
-
}: CentrifugoMonitorDialogProps) {
|
|
46
54
|
return (
|
|
47
|
-
<Sheet open={open} onOpenChange={
|
|
55
|
+
<Sheet open={open} onOpenChange={(isOpen) => !isOpen && handleClose()}>
|
|
48
56
|
<SheetContent
|
|
49
|
-
side=
|
|
50
|
-
className=
|
|
57
|
+
side="right"
|
|
58
|
+
className="max-w-2xl w-[90vw] sm:w-[672px]"
|
|
51
59
|
>
|
|
52
60
|
<SheetHeader>
|
|
53
61
|
<SheetTitle className="flex items-center gap-2">
|
|
54
62
|
<Activity className="h-5 w-5" />
|
|
55
|
-
|
|
63
|
+
Centrifugo Monitor
|
|
56
64
|
</SheetTitle>
|
|
57
|
-
|
|
65
|
+
<SheetDescription>
|
|
66
|
+
Real-time WebSocket monitoring and debugging
|
|
67
|
+
</SheetDescription>
|
|
58
68
|
</SheetHeader>
|
|
59
69
|
|
|
60
70
|
<div className="mt-6">
|
|
61
|
-
<CentrifugoMonitor {
|
|
71
|
+
<CentrifugoMonitor variant={variant} />
|
|
62
72
|
</div>
|
|
63
73
|
</SheetContent>
|
|
64
74
|
</Sheet>
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Centrifugo Monitor FAB Component
|
|
3
3
|
*
|
|
4
|
-
* Floating Action Button that opens CentrifugoMonitorDialog
|
|
4
|
+
* Floating Action Button that opens CentrifugoMonitorDialog via events
|
|
5
5
|
* Replaces the old DebugPanel FAB
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
'use client';
|
|
9
9
|
|
|
10
|
-
import React
|
|
10
|
+
import React from 'react';
|
|
11
11
|
import { Activity } from 'lucide-react';
|
|
12
|
-
import {
|
|
12
|
+
import { emitOpenMonitorDialog, type OpenMonitorDialogPayload } from '../../events';
|
|
13
13
|
|
|
14
14
|
// ─────────────────────────────────────────────────────────────────────────
|
|
15
15
|
// Types
|
|
16
16
|
// ─────────────────────────────────────────────────────────────────────────
|
|
17
17
|
|
|
18
|
-
export interface CentrifugoMonitorFABProps
|
|
18
|
+
export interface CentrifugoMonitorFABProps {
|
|
19
19
|
position?: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
|
|
20
20
|
size?: 'sm' | 'md' | 'lg';
|
|
21
|
+
variant?: OpenMonitorDialogPayload['variant'];
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -27,9 +28,8 @@ export interface CentrifugoMonitorFABProps extends Omit<CentrifugoMonitorDialogP
|
|
|
27
28
|
export function CentrifugoMonitorFAB({
|
|
28
29
|
position = 'bottom-left',
|
|
29
30
|
size = 'md',
|
|
30
|
-
|
|
31
|
+
variant = 'full',
|
|
31
32
|
}: CentrifugoMonitorFABProps) {
|
|
32
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
33
33
|
|
|
34
34
|
// Position styles
|
|
35
35
|
const positionStyles = {
|
|
@@ -52,30 +52,24 @@ export function CentrifugoMonitorFAB({
|
|
|
52
52
|
lg: 'h-7 w-7',
|
|
53
53
|
};
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
<button
|
|
59
|
-
onClick={() => setIsOpen(true)}
|
|
60
|
-
className="rounded-full bg-primary text-primary-foreground shadow-lg hover:bg-primary/90 transition-all duration-200 flex items-center justify-center hover:scale-110"
|
|
61
|
-
style={{
|
|
62
|
-
position: 'fixed',
|
|
63
|
-
...positionStyles[position],
|
|
64
|
-
...sizeStyles[size],
|
|
65
|
-
zIndex: 9999,
|
|
66
|
-
}}
|
|
67
|
-
aria-label="Open Centrifugo Monitor"
|
|
68
|
-
>
|
|
69
|
-
<Activity className={iconSizes[size]} />
|
|
70
|
-
</button>
|
|
55
|
+
const handleClick = () => {
|
|
56
|
+
emitOpenMonitorDialog({ variant });
|
|
57
|
+
};
|
|
71
58
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
59
|
+
return (
|
|
60
|
+
<button
|
|
61
|
+
onClick={handleClick}
|
|
62
|
+
className="rounded-full bg-primary text-primary-foreground shadow-lg hover:bg-primary/90 transition-all duration-200 flex items-center justify-center hover:scale-110"
|
|
63
|
+
style={{
|
|
64
|
+
position: 'fixed',
|
|
65
|
+
...positionStyles[position],
|
|
66
|
+
...sizeStyles[size],
|
|
67
|
+
zIndex: 9999,
|
|
68
|
+
}}
|
|
69
|
+
aria-label="Open Centrifugo Monitor"
|
|
70
|
+
>
|
|
71
|
+
<Activity className={iconSizes[size]} />
|
|
72
|
+
</button>
|
|
79
73
|
);
|
|
80
74
|
}
|
|
81
75
|
|
|
@@ -2,23 +2,22 @@
|
|
|
2
2
|
* Centrifugo Monitor Widget Component
|
|
3
3
|
*
|
|
4
4
|
* Card-based widget for dashboards
|
|
5
|
-
*
|
|
5
|
+
* Opens monitor dialog via events
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
'use client';
|
|
9
9
|
|
|
10
|
-
import React
|
|
10
|
+
import React from 'react';
|
|
11
11
|
import { Card, CardContent, CardHeader, CardTitle, Button } from '@djangocfg/ui';
|
|
12
12
|
import { Activity, Maximize2 } from 'lucide-react';
|
|
13
13
|
import { ConnectionStatus } from '../ConnectionStatus';
|
|
14
|
-
import {
|
|
15
|
-
import type { CentrifugoMonitorProps } from './CentrifugoMonitor';
|
|
14
|
+
import { emitOpenMonitorDialog } from '../../events';
|
|
16
15
|
|
|
17
16
|
// ─────────────────────────────────────────────────────────────────────────
|
|
18
17
|
// Types
|
|
19
18
|
// ─────────────────────────────────────────────────────────────────────────
|
|
20
19
|
|
|
21
|
-
export interface CentrifugoMonitorWidgetProps
|
|
20
|
+
export interface CentrifugoMonitorWidgetProps {
|
|
22
21
|
title?: string;
|
|
23
22
|
showExpandButton?: boolean;
|
|
24
23
|
className?: string;
|
|
@@ -32,43 +31,32 @@ export function CentrifugoMonitorWidget({
|
|
|
32
31
|
title = 'WebSocket Monitor',
|
|
33
32
|
showExpandButton = true,
|
|
34
33
|
className = '',
|
|
35
|
-
...monitorProps
|
|
36
34
|
}: CentrifugoMonitorWidgetProps) {
|
|
37
|
-
const
|
|
35
|
+
const handleExpand = () => {
|
|
36
|
+
emitOpenMonitorDialog({ variant: 'full' });
|
|
37
|
+
};
|
|
38
38
|
|
|
39
39
|
return (
|
|
40
|
-
|
|
41
|
-
<
|
|
42
|
-
<
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
<
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
</Card>
|
|
61
|
-
|
|
62
|
-
{/* Full monitor dialog */}
|
|
63
|
-
{showExpandButton && (
|
|
64
|
-
<CentrifugoMonitorDialog
|
|
65
|
-
open={isDialogOpen}
|
|
66
|
-
onOpenChange={setIsDialogOpen}
|
|
67
|
-
variant="full"
|
|
68
|
-
{...monitorProps}
|
|
69
|
-
/>
|
|
70
|
-
)}
|
|
71
|
-
</>
|
|
40
|
+
<Card className={className}>
|
|
41
|
+
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
42
|
+
<CardTitle className="text-sm font-medium flex items-center gap-2">
|
|
43
|
+
<Activity className="h-4 w-4" />
|
|
44
|
+
{title}
|
|
45
|
+
</CardTitle>
|
|
46
|
+
{showExpandButton && (
|
|
47
|
+
<Button
|
|
48
|
+
size="sm"
|
|
49
|
+
variant="ghost"
|
|
50
|
+
onClick={handleExpand}
|
|
51
|
+
>
|
|
52
|
+
<Maximize2 className="h-4 w-4" />
|
|
53
|
+
</Button>
|
|
54
|
+
)}
|
|
55
|
+
</CardHeader>
|
|
56
|
+
<CardContent>
|
|
57
|
+
<ConnectionStatus variant="detailed" showUptime showSubscriptions />
|
|
58
|
+
</CardContent>
|
|
59
|
+
</Card>
|
|
72
60
|
);
|
|
73
61
|
}
|
|
74
62
|
|
|
@@ -8,7 +8,6 @@ export { CentrifugoMonitorFAB } from './CentrifugoMonitorFAB';
|
|
|
8
8
|
export { CentrifugoMonitorWidget } from './CentrifugoMonitorWidget';
|
|
9
9
|
|
|
10
10
|
export type { CentrifugoMonitorProps } from './CentrifugoMonitor';
|
|
11
|
-
export type { CentrifugoMonitorDialogProps } from './CentrifugoMonitorDialog';
|
|
12
11
|
export type { CentrifugoMonitorFABProps } from './CentrifugoMonitorFAB';
|
|
13
12
|
export type { CentrifugoMonitorWidgetProps } from './CentrifugoMonitorWidget';
|
|
14
13
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Connection Status Card Component
|
|
3
3
|
*
|
|
4
4
|
* Card wrapper for ConnectionStatus - ready for dashboard widgets
|
|
5
|
-
* Clickable - opens CentrifugoMonitorDialog on click
|
|
5
|
+
* Clickable - opens CentrifugoMonitorDialog on click via events
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
'use client';
|
|
@@ -12,7 +12,7 @@ import { Card, CardContent, CardHeader, CardTitle } from '@djangocfg/ui';
|
|
|
12
12
|
import { Wifi, WifiOff } from 'lucide-react';
|
|
13
13
|
import { useCentrifugo } from '../../providers/CentrifugoProvider';
|
|
14
14
|
import { ConnectionStatus } from './ConnectionStatus';
|
|
15
|
-
import {
|
|
15
|
+
import { emitOpenMonitorDialog } from '../../events';
|
|
16
16
|
|
|
17
17
|
// ─────────────────────────────────────────────────────────────────────────
|
|
18
18
|
// Types
|
|
@@ -34,37 +34,33 @@ export function ConnectionStatusCard({
|
|
|
34
34
|
className = '',
|
|
35
35
|
}: ConnectionStatusCardProps) {
|
|
36
36
|
const { isConnected } = useCentrifugo();
|
|
37
|
-
const [dialogOpen, setDialogOpen] = React.useState(false);
|
|
38
37
|
|
|
39
38
|
const statusColor = isConnected ? 'border-green-500' : 'border-red-500';
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
className={`${statusColor} ${className} cursor-pointer hover:shadow-lg transition-shadow`}
|
|
45
|
-
style={{ borderLeftWidth: '4px' }}
|
|
46
|
-
onClick={() => setDialogOpen(true)}
|
|
47
|
-
>
|
|
48
|
-
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
49
|
-
<CardTitle className="text-sm font-medium">WebSocket</CardTitle>
|
|
50
|
-
<div className={isConnected ? 'text-green-600' : 'text-red-600'}>
|
|
51
|
-
{isConnected ? <Wifi className="h-4 w-4" /> : <WifiOff className="h-4 w-4" />}
|
|
52
|
-
</div>
|
|
53
|
-
</CardHeader>
|
|
54
|
-
<CardContent>
|
|
55
|
-
<ConnectionStatus
|
|
56
|
-
variant="detailed"
|
|
57
|
-
showUptime={showUptime}
|
|
58
|
-
showSubscriptions={showSubscriptions}
|
|
59
|
-
/>
|
|
60
|
-
</CardContent>
|
|
61
|
-
</Card>
|
|
40
|
+
const handleClick = () => {
|
|
41
|
+
emitOpenMonitorDialog({ variant: 'full' });
|
|
42
|
+
};
|
|
62
43
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
44
|
+
return (
|
|
45
|
+
<Card
|
|
46
|
+
className={`${statusColor} ${className} cursor-pointer hover:shadow-lg transition-shadow`}
|
|
47
|
+
style={{ borderLeftWidth: '4px' }}
|
|
48
|
+
onClick={handleClick}
|
|
49
|
+
>
|
|
50
|
+
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
51
|
+
<CardTitle className="text-sm font-medium">WebSocket</CardTitle>
|
|
52
|
+
<div className={isConnected ? 'text-green-600' : 'text-red-600'}>
|
|
53
|
+
{isConnected ? <Wifi className="h-4 w-4" /> : <WifiOff className="h-4 w-4" />}
|
|
54
|
+
</div>
|
|
55
|
+
</CardHeader>
|
|
56
|
+
<CardContent>
|
|
57
|
+
<ConnectionStatus
|
|
58
|
+
variant="detailed"
|
|
59
|
+
showUptime={showUptime}
|
|
60
|
+
showSubscriptions={showSubscriptions}
|
|
61
|
+
/>
|
|
62
|
+
</CardContent>
|
|
63
|
+
</Card>
|
|
68
64
|
);
|
|
69
65
|
}
|
|
70
66
|
|
package/src/events.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centrifugo Package Events
|
|
3
|
+
*
|
|
4
|
+
* Event-driven communication for Centrifugo monitor dialog
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { events } from '@djangocfg/ui';
|
|
8
|
+
|
|
9
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
10
|
+
// Event Types
|
|
11
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
export const CENTRIFUGO_MONITOR_EVENTS = {
|
|
14
|
+
OPEN_MONITOR_DIALOG: 'CENTRIFUGO_OPEN_MONITOR_DIALOG',
|
|
15
|
+
CLOSE_MONITOR_DIALOG: 'CENTRIFUGO_CLOSE_MONITOR_DIALOG',
|
|
16
|
+
} as const;
|
|
17
|
+
|
|
18
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
19
|
+
// Event Payload Types
|
|
20
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
export interface OpenMonitorDialogPayload {
|
|
23
|
+
variant?: 'compact' | 'full' | 'minimal';
|
|
24
|
+
defaultTab?: 'connection' | 'messages' | 'subscriptions';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
28
|
+
// Event Emitters
|
|
29
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
export const emitOpenMonitorDialog = (payload?: OpenMonitorDialogPayload) => {
|
|
32
|
+
events.publish({
|
|
33
|
+
type: CENTRIFUGO_MONITOR_EVENTS.OPEN_MONITOR_DIALOG,
|
|
34
|
+
payload: payload || {},
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const emitCloseMonitorDialog = () => {
|
|
39
|
+
events.publish({
|
|
40
|
+
type: CENTRIFUGO_MONITOR_EVENTS.CLOSE_MONITOR_DIALOG,
|
|
41
|
+
payload: {},
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
package/src/index.ts
CHANGED
|
@@ -99,6 +99,12 @@ export type {
|
|
|
99
99
|
export { centrifugoConfig, isDevelopment, isProduction, isStaticBuild } from './config';
|
|
100
100
|
export type { CentrifugoConfig } from './config';
|
|
101
101
|
|
|
102
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
103
|
+
// Events
|
|
104
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
105
|
+
|
|
106
|
+
export * from './events';
|
|
107
|
+
|
|
102
108
|
// ─────────────────────────────────────────────────────────────────────────
|
|
103
109
|
// Components (Universal, composable monitoring components)
|
|
104
110
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -11,9 +11,10 @@ import { createContext, useContext, useState, useEffect, useCallback, useRef, us
|
|
|
11
11
|
import { useAuth } from '@djangocfg/layouts';
|
|
12
12
|
import { CentrifugoRPCClient } from '../../core/client';
|
|
13
13
|
import { createLogger } from '../../core/logger';
|
|
14
|
-
import type { ConnectionState, CentrifugoToken } from '../../core/types';
|
|
14
|
+
import type { ConnectionState, CentrifugoToken, ActiveSubscription } from '../../core/types';
|
|
15
15
|
import { LogsProvider } from '../LogsProvider';
|
|
16
16
|
import { isStaticBuild } from '../../config';
|
|
17
|
+
import { CentrifugoMonitorDialog } from '../../components/CentrifugoMonitor/CentrifugoMonitorDialog';
|
|
17
18
|
|
|
18
19
|
// ─────────────────────────────────────────────────────────────────────────
|
|
19
20
|
// Context
|
|
@@ -32,7 +33,7 @@ export interface CentrifugoContextValue {
|
|
|
32
33
|
// Connection Info
|
|
33
34
|
uptime: number; // seconds
|
|
34
35
|
subscriptions: string[];
|
|
35
|
-
activeSubscriptions:
|
|
36
|
+
activeSubscriptions: ActiveSubscription[];
|
|
36
37
|
|
|
37
38
|
// Controls
|
|
38
39
|
connect: () => Promise<void>;
|
|
@@ -76,7 +77,7 @@ function CentrifugoProviderInner({
|
|
|
76
77
|
const [connectionTime, setConnectionTime] = useState<Date | null>(null);
|
|
77
78
|
const [uptime, setUptime] = useState<number>(0);
|
|
78
79
|
const [subscriptions, setSubscriptions] = useState<string[]>([]);
|
|
79
|
-
const [activeSubscriptions, setActiveSubscriptions] = useState<
|
|
80
|
+
const [activeSubscriptions, setActiveSubscriptions] = useState<ActiveSubscription[]>([]);
|
|
80
81
|
|
|
81
82
|
const logger = useMemo(() => createLogger({ source: 'provider' }), []);
|
|
82
83
|
|
|
@@ -145,7 +146,7 @@ function CentrifugoProviderInner({
|
|
|
145
146
|
setSubscriptions(subs);
|
|
146
147
|
|
|
147
148
|
// Convert to ActiveSubscription format
|
|
148
|
-
const activeSubs:
|
|
149
|
+
const activeSubs: ActiveSubscription[] = subs.map((channel) => ({
|
|
149
150
|
channel,
|
|
150
151
|
type: 'client' as const,
|
|
151
152
|
subscribedAt: Date.now(),
|
|
@@ -337,13 +338,16 @@ function CentrifugoProviderInner({
|
|
|
337
338
|
}
|
|
338
339
|
|
|
339
340
|
// ─────────────────────────────────────────────────────────────────────────
|
|
340
|
-
// Main Provider (wraps LogsProvider)
|
|
341
|
+
// Main Provider (wraps LogsProvider and includes Dialog)
|
|
341
342
|
// ─────────────────────────────────────────────────────────────────────────
|
|
342
343
|
|
|
343
344
|
export function CentrifugoProvider(props: CentrifugoProviderProps) {
|
|
344
345
|
return (
|
|
345
346
|
<LogsProvider>
|
|
346
|
-
<CentrifugoProviderInner {...props}
|
|
347
|
+
<CentrifugoProviderInner {...props}>
|
|
348
|
+
{props.children}
|
|
349
|
+
<CentrifugoMonitorDialog />
|
|
350
|
+
</CentrifugoProviderInner>
|
|
347
351
|
</LogsProvider>
|
|
348
352
|
);
|
|
349
353
|
}
|