@djangocfg/centrifugo 1.0.1 → 1.0.3
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 +345 -34
- package/package.json +6 -4
- package/src/config.ts +1 -1
- package/src/core/client/CentrifugoRPCClient.ts +281 -0
- package/src/core/client/index.ts +5 -0
- package/src/core/index.ts +15 -0
- package/src/core/logger/LogsStore.ts +101 -0
- package/src/core/logger/createLogger.ts +79 -0
- package/src/core/logger/index.ts +9 -0
- package/src/core/types/index.ts +68 -0
- package/src/debug/ConnectionTab/ConnectionTab.tsx +160 -0
- package/src/debug/ConnectionTab/index.ts +5 -0
- package/src/debug/DebugPanel/DebugPanel.tsx +88 -0
- package/src/debug/DebugPanel/index.ts +5 -0
- package/src/debug/LogsTab/LogsTab.tsx +236 -0
- package/src/debug/LogsTab/index.ts +5 -0
- package/src/debug/SubscriptionsTab/SubscriptionsTab.tsx +135 -0
- package/src/debug/SubscriptionsTab/index.ts +5 -0
- package/src/debug/index.ts +11 -0
- package/src/hooks/index.ts +2 -5
- package/src/hooks/useSubscription.ts +66 -65
- package/src/index.ts +94 -13
- package/src/providers/CentrifugoProvider/CentrifugoProvider.tsx +380 -0
- package/src/providers/CentrifugoProvider/index.ts +6 -0
- package/src/providers/LogsProvider/LogsProvider.tsx +107 -0
- package/src/providers/LogsProvider/index.ts +6 -0
- package/src/providers/index.ts +9 -0
- package/API_GENERATOR.md +0 -253
- package/src/components/CentrifugoDebug.tsx +0 -182
- package/src/components/index.ts +0 -5
- package/src/context/CentrifugoProvider.tsx +0 -228
- package/src/context/index.ts +0 -5
- package/src/hooks/useLogger.ts +0 -69
- package/src/types/index.ts +0 -45
package/README.md
CHANGED
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
# @djangocfg/centrifugo
|
|
2
2
|
|
|
3
|
-
WebSocket client
|
|
3
|
+
Professional Centrifugo WebSocket client with React integration and comprehensive debugging tools.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔌 **Robust WebSocket Connection** - Auto-reconnect, error handling, and connection state management
|
|
8
|
+
- 📊 **Advanced Logging System** - Circular buffer with dual output (console + in-memory accumulation)
|
|
9
|
+
- 🐛 **Debug UI** - Development-only debug panel with bash-like logs viewer
|
|
10
|
+
- ⚛️ **React Integration** - Context providers and hooks for seamless integration
|
|
11
|
+
- 🎯 **Type-Safe** - Full TypeScript support with comprehensive type definitions
|
|
12
|
+
- 🏗️ **Platform-Agnostic Core** - Core modules can be used without React
|
|
13
|
+
- 🎨 **Beautiful UI Components** - Pre-built components using shadcn/ui
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
src/
|
|
19
|
+
├── core/ # Platform-agnostic (no React dependencies)
|
|
20
|
+
│ ├── client/ # CentrifugoRPCClient - WebSocket client
|
|
21
|
+
│ ├── logger/ # Logging system with circular buffer
|
|
22
|
+
│ └── types/ # TypeScript type definitions
|
|
23
|
+
├── providers/ # React Context providers
|
|
24
|
+
│ ├── CentrifugoProvider/ # Main connection provider
|
|
25
|
+
│ └── LogsProvider/ # Logs accumulation provider
|
|
26
|
+
├── hooks/ # React hooks
|
|
27
|
+
│ └── useSubscription.ts # Channel subscription hook
|
|
28
|
+
└── debug/ # Development-only debug UI (lazy loaded)
|
|
29
|
+
├── DebugPanel/ # Main debug panel with FAB button
|
|
30
|
+
├── ConnectionTab/ # Connection status and controls
|
|
31
|
+
├── LogsTab/ # Bash-like logs viewer
|
|
32
|
+
└── SubscriptionsTab/ # Active subscriptions list
|
|
33
|
+
```
|
|
4
34
|
|
|
5
35
|
## Installation
|
|
6
36
|
|
|
@@ -8,77 +38,358 @@ WebSocket client package for Django-CFG + Centrifugo integration.
|
|
|
8
38
|
pnpm add @djangocfg/centrifugo
|
|
9
39
|
```
|
|
10
40
|
|
|
11
|
-
##
|
|
41
|
+
## Quick Start
|
|
12
42
|
|
|
13
43
|
### 1. Wrap your app with CentrifugoProvider
|
|
14
44
|
|
|
15
45
|
```tsx
|
|
16
|
-
import { CentrifugoProvider } from '@djangocfg/centrifugo';
|
|
46
|
+
import { CentrifugoProvider, DebugPanel } from '@djangocfg/centrifugo';
|
|
17
47
|
|
|
18
48
|
function App() {
|
|
19
49
|
return (
|
|
20
|
-
<CentrifugoProvider
|
|
50
|
+
<CentrifugoProvider
|
|
51
|
+
enabled={true}
|
|
52
|
+
autoConnect={true}
|
|
53
|
+
>
|
|
21
54
|
<YourApp />
|
|
55
|
+
|
|
56
|
+
{/* Debug panel (only shows in development) */}
|
|
57
|
+
<DebugPanel />
|
|
22
58
|
</CentrifugoProvider>
|
|
23
59
|
);
|
|
24
60
|
}
|
|
25
61
|
```
|
|
26
62
|
|
|
27
|
-
### 2. Use
|
|
63
|
+
### 2. Use the connection in your components
|
|
28
64
|
|
|
29
65
|
```tsx
|
|
30
|
-
import { useCentrifugo
|
|
66
|
+
import { useCentrifugo } from '@djangocfg/centrifugo';
|
|
67
|
+
|
|
68
|
+
function YourComponent() {
|
|
69
|
+
const { isConnected, connectionState, uptime } = useCentrifugo();
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<div>
|
|
73
|
+
<p>Status: {isConnected ? 'Connected' : 'Disconnected'}</p>
|
|
74
|
+
<p>State: {connectionState}</p>
|
|
75
|
+
<p>Uptime: {uptime}s</p>
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 3. Subscribe to channels
|
|
31
82
|
|
|
32
|
-
|
|
33
|
-
|
|
83
|
+
```tsx
|
|
84
|
+
import { useSubscription } from '@djangocfg/centrifugo';
|
|
34
85
|
|
|
35
|
-
|
|
86
|
+
function NotificationsComponent() {
|
|
87
|
+
const { data, isSubscribed } = useSubscription({
|
|
36
88
|
channel: 'notifications',
|
|
37
|
-
|
|
89
|
+
enabled: true,
|
|
90
|
+
onPublication: (data) => {
|
|
91
|
+
console.log('New notification:', data);
|
|
92
|
+
},
|
|
93
|
+
onError: (error) => {
|
|
94
|
+
console.error('Subscription error:', error);
|
|
95
|
+
},
|
|
38
96
|
});
|
|
39
97
|
|
|
40
|
-
return
|
|
98
|
+
return (
|
|
99
|
+
<div>
|
|
100
|
+
<p>Subscribed: {isSubscribed ? 'Yes' : 'No'}</p>
|
|
101
|
+
{data && <pre>{JSON.stringify(data, null, 2)}</pre>}
|
|
102
|
+
</div>
|
|
103
|
+
);
|
|
41
104
|
}
|
|
42
105
|
```
|
|
43
106
|
|
|
44
|
-
|
|
107
|
+
## Core APIs
|
|
108
|
+
|
|
109
|
+
### CentrifugoProvider
|
|
110
|
+
|
|
111
|
+
Main provider that manages the WebSocket connection.
|
|
112
|
+
|
|
113
|
+
**Props:**
|
|
114
|
+
- `enabled?: boolean` - Enable/disable the connection (default: `false`)
|
|
115
|
+
- `url?: string` - WebSocket URL (falls back to user.centrifugo.centrifugo_url)
|
|
116
|
+
- `autoConnect?: boolean` - Auto-connect when authenticated (default: `true`)
|
|
117
|
+
|
|
118
|
+
**Context Value:**
|
|
119
|
+
```typescript
|
|
120
|
+
interface CentrifugoContextValue {
|
|
121
|
+
// Client
|
|
122
|
+
client: CentrifugoRPCClient | null;
|
|
123
|
+
|
|
124
|
+
// Connection State
|
|
125
|
+
isConnected: boolean;
|
|
126
|
+
isConnecting: boolean;
|
|
127
|
+
error: Error | null;
|
|
128
|
+
connectionState: 'disconnected' | 'connecting' | 'connected' | 'error';
|
|
129
|
+
|
|
130
|
+
// Connection Info
|
|
131
|
+
uptime: number; // seconds
|
|
132
|
+
subscriptions: string[];
|
|
133
|
+
activeSubscriptions: ActiveSubscription[];
|
|
134
|
+
|
|
135
|
+
// Controls
|
|
136
|
+
connect: () => Promise<void>;
|
|
137
|
+
disconnect: () => void;
|
|
138
|
+
reconnect: () => Promise<void>;
|
|
139
|
+
unsubscribe: (channel: string) => void;
|
|
140
|
+
|
|
141
|
+
// Config
|
|
142
|
+
enabled: boolean;
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### useCentrifugo()
|
|
147
|
+
|
|
148
|
+
Hook to access the Centrifugo connection context.
|
|
45
149
|
|
|
46
150
|
```tsx
|
|
47
|
-
|
|
151
|
+
const {
|
|
152
|
+
client,
|
|
153
|
+
isConnected,
|
|
154
|
+
connectionState,
|
|
155
|
+
connect,
|
|
156
|
+
disconnect,
|
|
157
|
+
reconnect,
|
|
158
|
+
} = useCentrifugo();
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### useSubscription()
|
|
162
|
+
|
|
163
|
+
Hook to subscribe to a channel with auto-cleanup.
|
|
48
164
|
|
|
49
|
-
|
|
50
|
-
|
|
165
|
+
```tsx
|
|
166
|
+
const { data, isSubscribed, error } = useSubscription({
|
|
167
|
+
channel: 'my-channel',
|
|
168
|
+
enabled: true, // optional
|
|
169
|
+
onPublication: (data) => {
|
|
170
|
+
// Handle new data
|
|
171
|
+
},
|
|
172
|
+
onError: (error) => {
|
|
173
|
+
// Handle error
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Options:**
|
|
179
|
+
```typescript
|
|
180
|
+
interface UseSubscriptionOptions<T> {
|
|
181
|
+
channel: string;
|
|
182
|
+
enabled?: boolean;
|
|
183
|
+
onPublication?: (data: T) => void;
|
|
184
|
+
onError?: (error: Error) => void;
|
|
51
185
|
}
|
|
52
186
|
```
|
|
53
187
|
|
|
54
|
-
|
|
188
|
+
### LogsProvider
|
|
55
189
|
|
|
56
|
-
|
|
57
|
-
- `CentrifugoProvider` - WebSocket connection provider
|
|
58
|
-
- `useCentrifugo` - Access connection state and client
|
|
190
|
+
Provider for accessing accumulated logs.
|
|
59
191
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
192
|
+
```tsx
|
|
193
|
+
const {
|
|
194
|
+
logs, // All logs
|
|
195
|
+
filteredLogs, // Filtered logs
|
|
196
|
+
count, // Total count
|
|
197
|
+
filter, // Current filter
|
|
198
|
+
setFilter, // Update filter
|
|
199
|
+
clearLogs, // Clear all logs
|
|
200
|
+
} = useLogs();
|
|
201
|
+
```
|
|
63
202
|
|
|
64
|
-
|
|
65
|
-
- `CentrifugoDebug` - Development debug panel
|
|
203
|
+
## Debug Panel
|
|
66
204
|
|
|
67
|
-
|
|
68
|
-
- `CentrifugoConfig` - Configuration interface
|
|
69
|
-
- `CentrifugoToken` - JWT token structure
|
|
70
|
-
- `User` - User type with Centrifugo data
|
|
71
|
-
- `AuthContext` - Authentication context interface
|
|
72
|
-
- `CentrifugoProviderProps` - Provider props
|
|
73
|
-
- `CentrifugoContextValue` - Context value type
|
|
205
|
+
The debug panel is a development-only UI that provides:
|
|
74
206
|
|
|
75
|
-
|
|
207
|
+
1. **Connection Tab** - View connection status, uptime, and controls
|
|
208
|
+
2. **Logs Tab** - Bash-like logs viewer with:
|
|
209
|
+
- Filter by level (debug/info/success/warning/error)
|
|
210
|
+
- Filter by source (client/provider/subscription/system)
|
|
211
|
+
- Search functionality with debounce
|
|
212
|
+
- Auto-scroll toggle
|
|
213
|
+
- Expandable JSON data with syntax highlighting
|
|
214
|
+
3. **Subscriptions Tab** - View and manage active subscriptions
|
|
215
|
+
|
|
216
|
+
**Usage:**
|
|
217
|
+
```tsx
|
|
218
|
+
import { DebugPanel } from '@djangocfg/centrifugo';
|
|
219
|
+
|
|
220
|
+
function App() {
|
|
221
|
+
return (
|
|
222
|
+
<>
|
|
223
|
+
<YourApp />
|
|
224
|
+
<DebugPanel />
|
|
225
|
+
</>
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
The panel only renders in development mode (`NODE_ENV === 'development'`). It appears as a floating action button (FAB) in the bottom-left corner.
|
|
231
|
+
|
|
232
|
+
## Logging System
|
|
233
|
+
|
|
234
|
+
The package includes a sophisticated logging system with:
|
|
76
235
|
|
|
77
|
-
|
|
236
|
+
- **Circular Buffer** - Stores up to 500 logs (configurable)
|
|
237
|
+
- **Dual Output** - Console (dev only) + in-memory store (always)
|
|
238
|
+
- **Structured Logs** - Timestamp, level, source, message, and optional data
|
|
239
|
+
- **Real-time Updates** - Subscribe to log changes for React updates
|
|
240
|
+
|
|
241
|
+
**Creating a Logger:**
|
|
242
|
+
```typescript
|
|
243
|
+
import { createLogger } from '@djangocfg/centrifugo';
|
|
244
|
+
|
|
245
|
+
const logger = createLogger({
|
|
246
|
+
source: 'my-module', // or 'client' | 'provider' | 'subscription' | 'system'
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
logger.debug('Debug message', { extra: 'data' });
|
|
250
|
+
logger.info('Info message');
|
|
251
|
+
logger.success('Success message');
|
|
252
|
+
logger.warning('Warning message');
|
|
253
|
+
logger.error('Error message', error);
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Accessing Logs:**
|
|
257
|
+
```typescript
|
|
258
|
+
import { getGlobalLogsStore } from '@djangocfg/centrifugo';
|
|
259
|
+
|
|
260
|
+
const logsStore = getGlobalLogsStore();
|
|
261
|
+
|
|
262
|
+
// Get all logs
|
|
263
|
+
const logs = logsStore.getAll();
|
|
264
|
+
|
|
265
|
+
// Subscribe to changes
|
|
266
|
+
const unsubscribe = logsStore.subscribe((logs) => {
|
|
267
|
+
console.log('Logs updated:', logs);
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// Clear logs
|
|
271
|
+
logsStore.clear();
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Advanced Usage
|
|
275
|
+
|
|
276
|
+
### Using the Core Client (without React)
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
import { CentrifugoRPCClient, createLogger } from '@djangocfg/centrifugo';
|
|
280
|
+
|
|
281
|
+
const logger = createLogger({ source: 'client' });
|
|
282
|
+
const client = new CentrifugoRPCClient(
|
|
283
|
+
'ws://localhost:8000/ws',
|
|
284
|
+
'your-token',
|
|
285
|
+
'user-id',
|
|
286
|
+
30000, // timeout
|
|
287
|
+
logger
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
await client.connect();
|
|
291
|
+
await client.subscribe('channel-name');
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Custom Log Filters
|
|
295
|
+
|
|
296
|
+
```tsx
|
|
297
|
+
import { useLogs } from '@djangocfg/centrifugo';
|
|
298
|
+
|
|
299
|
+
function CustomLogsView() {
|
|
300
|
+
const { logs, setFilter } = useLogs();
|
|
301
|
+
|
|
302
|
+
return (
|
|
303
|
+
<div>
|
|
304
|
+
<button onClick={() => setFilter({ level: 'error' })}>
|
|
305
|
+
Show Errors Only
|
|
306
|
+
</button>
|
|
307
|
+
<button onClick={() => setFilter({ source: 'client' })}>
|
|
308
|
+
Show Client Logs
|
|
309
|
+
</button>
|
|
310
|
+
<button onClick={() => setFilter({ search: 'WebSocket' })}>
|
|
311
|
+
Search "WebSocket"
|
|
312
|
+
</button>
|
|
313
|
+
<button onClick={() => setFilter({})}>
|
|
314
|
+
Clear Filters
|
|
315
|
+
</button>
|
|
316
|
+
</div>
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## TypeScript Support
|
|
322
|
+
|
|
323
|
+
The package is fully typed with comprehensive TypeScript definitions:
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
import type {
|
|
327
|
+
// Connection
|
|
328
|
+
ConnectionState,
|
|
329
|
+
CentrifugoToken,
|
|
330
|
+
User,
|
|
331
|
+
|
|
332
|
+
// Logs
|
|
333
|
+
LogLevel,
|
|
334
|
+
LogEntry,
|
|
335
|
+
|
|
336
|
+
// Subscriptions
|
|
337
|
+
ActiveSubscription,
|
|
338
|
+
|
|
339
|
+
// Client
|
|
340
|
+
CentrifugoClientConfig,
|
|
341
|
+
CentrifugoClientState,
|
|
342
|
+
|
|
343
|
+
// Provider
|
|
344
|
+
CentrifugoProviderProps,
|
|
345
|
+
CentrifugoContextValue,
|
|
346
|
+
|
|
347
|
+
// Hooks
|
|
348
|
+
UseSubscriptionOptions,
|
|
349
|
+
UseSubscriptionResult,
|
|
350
|
+
} from '@djangocfg/centrifugo';
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## Migration from Old Version
|
|
354
|
+
|
|
355
|
+
If you're migrating from `src_old`, the main changes are:
|
|
356
|
+
|
|
357
|
+
1. **Import paths** - All imports now come from `@djangocfg/centrifugo`
|
|
358
|
+
2. **Provider structure** - `CentrifugoProvider` now wraps `LogsProvider`
|
|
359
|
+
3. **New hooks** - `useSubscription` replaces manual subscription management
|
|
360
|
+
4. **Debug UI** - New `DebugPanel` component replaces old debugging
|
|
361
|
+
5. **Logger API** - New `createLogger` with better structure
|
|
362
|
+
|
|
363
|
+
**Before:**
|
|
364
|
+
```tsx
|
|
365
|
+
import { WSRPCContext } from './rpc/WSRPCContext';
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
**After:**
|
|
369
|
+
```tsx
|
|
370
|
+
import { CentrifugoProvider, useCentrifugo } from '@djangocfg/centrifugo';
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## Development
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
# Build the package
|
|
377
|
+
pnpm build
|
|
378
|
+
|
|
379
|
+
# Type check
|
|
380
|
+
pnpm exec tsc --noEmit
|
|
381
|
+
|
|
382
|
+
# Run in development mode
|
|
383
|
+
pnpm dev
|
|
384
|
+
```
|
|
78
385
|
|
|
79
386
|
## Requirements
|
|
80
387
|
|
|
81
|
-
- React
|
|
388
|
+
- React 18+
|
|
82
389
|
- `@djangocfg/ui` - UI components
|
|
83
390
|
- `@djangocfg/layouts` - Layout components
|
|
84
391
|
- `centrifuge` - WebSocket client library
|
|
392
|
+
|
|
393
|
+
## License
|
|
394
|
+
|
|
395
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/centrifugo",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "WebSocket RPC client for Django-CFG + Centrifugo integration",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -19,17 +19,19 @@
|
|
|
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.28",
|
|
23
|
+
"@djangocfg/layouts": "^1.2.28",
|
|
24
24
|
"consola": "^3.4.2",
|
|
25
25
|
"lucide-react": "^0.468.0",
|
|
26
|
+
"moment": "^2.30.1",
|
|
26
27
|
"react": "^19.0.0",
|
|
27
28
|
"react-dom": "^19.0.0"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
|
-
"@djangocfg/typescript-config": "^1.2.
|
|
31
|
+
"@djangocfg/typescript-config": "^1.2.28",
|
|
31
32
|
"@types/react": "^19.0.6",
|
|
32
33
|
"@types/react-dom": "^19.0.2",
|
|
34
|
+
"moment": "^2.30.1",
|
|
33
35
|
"typescript": "^5.7.3"
|
|
34
36
|
}
|
|
35
37
|
}
|
package/src/config.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
export const isDevelopment = process.env.NODE_ENV === 'development';
|
|
6
6
|
export const isProduction = !isDevelopment;
|
|
7
|
-
export const isStaticBuild = process.env.
|
|
7
|
+
export const isStaticBuild = process.env.NEXT_PHASE === 'phase-production-build';
|
|
8
8
|
|
|
9
9
|
const showDebugPanel = isDevelopment && !isStaticBuild;
|
|
10
10
|
|