@robosystems/client 0.1.15 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/extensions/hooks.d.ts +1 -1
  2. package/package.json +48 -6
  3. package/sdk/client/client.gen.d.ts +2 -0
  4. package/sdk/client/client.gen.js +153 -0
  5. package/sdk/client/client.gen.ts +200 -0
  6. package/sdk/client/index.d.ts +7 -0
  7. package/sdk/client/index.js +15 -0
  8. package/sdk/client/index.ts +25 -0
  9. package/sdk/client/types.gen.d.ts +122 -0
  10. package/sdk/client/types.gen.js +4 -0
  11. package/sdk/client/types.gen.ts +233 -0
  12. package/sdk/client/utils.gen.d.ts +45 -0
  13. package/sdk/client/utils.gen.js +296 -0
  14. package/sdk/client/utils.gen.ts +419 -0
  15. package/sdk/client.gen.d.ts +12 -0
  16. package/sdk/client.gen.js +8 -0
  17. package/sdk/client.gen.ts +18 -0
  18. package/sdk/core/auth.gen.d.ts +18 -0
  19. package/sdk/core/auth.gen.js +18 -0
  20. package/sdk/core/auth.gen.ts +42 -0
  21. package/sdk/core/bodySerializer.gen.d.ts +17 -0
  22. package/sdk/core/bodySerializer.gen.js +57 -0
  23. package/sdk/core/bodySerializer.gen.ts +90 -0
  24. package/sdk/core/params.gen.d.ts +33 -0
  25. package/sdk/core/params.gen.js +92 -0
  26. package/sdk/core/params.gen.ts +153 -0
  27. package/sdk/core/pathSerializer.gen.d.ts +33 -0
  28. package/sdk/core/pathSerializer.gen.js +123 -0
  29. package/sdk/core/pathSerializer.gen.ts +181 -0
  30. package/sdk/core/types.gen.d.ts +78 -0
  31. package/sdk/core/types.gen.js +4 -0
  32. package/sdk/core/types.gen.ts +121 -0
  33. package/sdk/index.d.ts +2 -0
  34. package/sdk/index.js +19 -0
  35. package/sdk/index.ts +3 -0
  36. package/sdk/sdk.gen.d.ts +1249 -0
  37. package/sdk/sdk.gen.js +2572 -0
  38. package/sdk/sdk.gen.ts +2585 -0
  39. package/sdk/types.gen.d.ts +6347 -0
  40. package/sdk/types.gen.js +3 -0
  41. package/sdk/types.gen.ts +6852 -0
  42. package/sdk-extensions/OperationClient.d.ts +64 -0
  43. package/sdk-extensions/OperationClient.js +251 -0
  44. package/sdk-extensions/OperationClient.ts +322 -0
  45. package/sdk-extensions/QueryClient.d.ts +50 -0
  46. package/sdk-extensions/QueryClient.js +190 -0
  47. package/sdk-extensions/QueryClient.ts +283 -0
  48. package/sdk-extensions/README.md +672 -0
  49. package/sdk-extensions/SSEClient.d.ts +48 -0
  50. package/sdk-extensions/SSEClient.js +148 -0
  51. package/sdk-extensions/SSEClient.ts +189 -0
  52. package/sdk-extensions/config.d.ts +32 -0
  53. package/sdk-extensions/config.js +74 -0
  54. package/sdk-extensions/config.ts +91 -0
  55. package/sdk-extensions/hooks.d.ts +110 -0
  56. package/sdk-extensions/hooks.js +371 -0
  57. package/sdk-extensions/hooks.ts +438 -0
  58. package/sdk-extensions/index.d.ts +46 -0
  59. package/sdk-extensions/index.js +110 -0
  60. package/sdk-extensions/index.ts +123 -0
  61. package/sdk.gen.d.ts +210 -104
  62. package/sdk.gen.js +409 -287
  63. package/sdk.gen.ts +404 -282
  64. package/types.gen.d.ts +1218 -567
  65. package/types.gen.ts +1236 -566
  66. package/openapi-ts.config.js +0 -9
  67. package/prepare.js +0 -220
@@ -0,0 +1,672 @@
1
+ # RoboSystems Typescript Client Extensions
2
+
3
+ 🚀 **Enhanced SSE and Real-time Features** for the RoboSystems Typescript Client
4
+
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Overview
9
+
10
+ The RoboSystems Typescript Client Extensions provide production-ready enhancements for real-time operations:
11
+
12
+ - **Server-Sent Events (SSE)** with automatic reconnection and event replay
13
+ - **Smart Query Execution** with automatic queueing and progress monitoring
14
+ - **Operation Monitoring** for long-running tasks with real-time updates
15
+ - **Connection Management** with rate limiting and circuit breaker patterns
16
+ - **React Hooks** for seamless UI integration
17
+ - **Full TypeScript Support** with comprehensive type definitions
18
+
19
+ ## 🚀 Quick Start
20
+
21
+ ### Installation
22
+
23
+ The extensions are included with the main SDK:
24
+
25
+ ```bash
26
+ npm install @robosystems/client
27
+ # or
28
+ yarn add @robosystems/client
29
+ # or
30
+ pnpm add @robosystems/client
31
+ ```
32
+
33
+ ### Basic SSE Usage
34
+
35
+ ```typescript
36
+ import { SSEClient, EventType } from '@robosystems/client/extensions'
37
+
38
+ // Initialize SSE client
39
+ const sseClient = new SSEClient({
40
+ baseUrl: 'https://api.robosystems.ai',
41
+ credentials: 'include', // For cookie auth
42
+ maxRetries: 5,
43
+ retryDelay: 1000,
44
+ })
45
+
46
+ // Connect to operation stream
47
+ await sseClient.connect('operation-id-123')
48
+
49
+ // Listen for events
50
+ sseClient.on(EventType.OPERATION_PROGRESS, (data) => {
51
+ console.log(`Progress: ${data.message} (${data.percentage}%)`)
52
+ })
53
+
54
+ sseClient.on(EventType.DATA_CHUNK, (data) => {
55
+ console.log(`Received ${data.rows.length} rows`)
56
+ processRows(data.rows)
57
+ })
58
+
59
+ sseClient.on(EventType.OPERATION_COMPLETED, (data) => {
60
+ console.log('Operation completed:', data.result)
61
+ })
62
+
63
+ // Clean up when done
64
+ sseClient.close()
65
+ ```
66
+
67
+ ### Query Execution with Progress Monitoring
68
+
69
+ ```typescript
70
+ import { QueryClient } from '@robosystems/client/extensions'
71
+
72
+ const queryClient = new QueryClient({
73
+ baseUrl: 'https://api.robosystems.ai',
74
+ apiKey: 'your-api-key',
75
+ })
76
+
77
+ // Execute query with automatic SSE monitoring
78
+ const result = await queryClient.executeWithProgress(
79
+ 'your-graph-id',
80
+ 'MATCH (c:Company) RETURN c.name, c.revenue ORDER BY c.revenue DESC',
81
+ {
82
+ onProgress: (progress) => {
83
+ console.log(`${progress.current}/${progress.total} rows processed`)
84
+ },
85
+ onQueueUpdate: (position, estimatedWait) => {
86
+ console.log(`Queue position: ${position}, ETA: ${estimatedWait}s`)
87
+ },
88
+ }
89
+ )
90
+
91
+ console.log(`Query completed with ${result.rowCount} results`)
92
+ ```
93
+
94
+ ## 📊 SSE Event Types
95
+
96
+ The SDK supports all RoboSystems SSE event types:
97
+
98
+ ```typescript
99
+ enum EventType {
100
+ // Operation lifecycle
101
+ OPERATION_STARTED = 'operation_started',
102
+ OPERATION_PROGRESS = 'operation_progress',
103
+ OPERATION_COMPLETED = 'operation_completed',
104
+ OPERATION_ERROR = 'operation_error',
105
+ OPERATION_CANCELLED = 'operation_cancelled',
106
+
107
+ // Data streaming
108
+ DATA_CHUNK = 'data_chunk',
109
+ METADATA = 'metadata',
110
+
111
+ // Queue management
112
+ QUEUE_UPDATE = 'queue_update',
113
+
114
+ // Connection health
115
+ HEARTBEAT = 'heartbeat',
116
+ }
117
+ ```
118
+
119
+ ## 🔄 Advanced SSE Features
120
+
121
+ ### Automatic Reconnection
122
+
123
+ The SSE client automatically reconnects on connection loss with exponential backoff:
124
+
125
+ ```typescript
126
+ const sseClient = new SSEClient({
127
+ baseUrl: 'https://api.robosystems.ai',
128
+ maxRetries: 5, // Maximum reconnection attempts
129
+ retryDelay: 1000, // Initial retry delay (ms)
130
+ heartbeatInterval: 30000, // Heartbeat check interval
131
+ })
132
+
133
+ // Monitor reconnection attempts
134
+ sseClient.on('reconnecting', ({ attempt, delay, lastEventId }) => {
135
+ console.log(`Reconnecting (attempt ${attempt}) in ${delay}ms...`)
136
+ console.log(`Resuming from event ${lastEventId}`)
137
+ })
138
+
139
+ sseClient.on('max_retries_exceeded', (error) => {
140
+ console.error('Failed to reconnect after maximum attempts')
141
+ // Fallback to polling or show error to user
142
+ })
143
+ ```
144
+
145
+ ### Event Replay
146
+
147
+ SSE automatically resumes from the last received event after reconnection:
148
+
149
+ ```typescript
150
+ // Connect with specific starting sequence
151
+ await sseClient.connect('operation-id', fromSequence)
152
+
153
+ // The client tracks lastEventId automatically
154
+ sseClient.on('event', (event) => {
155
+ console.log(`Event ${event.id}: ${event.event}`)
156
+ // Events are guaranteed to be in sequence
157
+ })
158
+ ```
159
+
160
+ ### Rate Limiting & Connection Management
161
+
162
+ The SDK respects server-side rate limits:
163
+
164
+ - **Maximum 5 concurrent SSE connections per user**
165
+ - **10 new connections per minute rate limit**
166
+ - **Automatic circuit breaker for Redis failures**
167
+
168
+ ```typescript
169
+ // Handle rate limiting gracefully
170
+ try {
171
+ await sseClient.connect('operation-id')
172
+ } catch (error) {
173
+ if (error.status === 429) {
174
+ console.log('Rate limit exceeded - falling back to polling')
175
+ // Use polling fallback
176
+ const result = await pollOperation('operation-id')
177
+ } else if (error.status === 503) {
178
+ console.log('SSE temporarily unavailable - circuit breaker open')
179
+ // SSE system is degraded, use alternative method
180
+ }
181
+ }
182
+ ```
183
+
184
+ ## 🎯 Operation Monitoring
185
+
186
+ ### OperationClient for Long-Running Tasks
187
+
188
+ ```typescript
189
+ import { OperationClient, OperationStatus } from '@robosystems/client/extensions'
190
+
191
+ const operationClient = new OperationClient({
192
+ baseUrl: 'https://api.robosystems.ai',
193
+ apiKey: 'your-api-key',
194
+ })
195
+
196
+ // Monitor any long-running operation
197
+ const result = await operationClient.monitor('operation-id', {
198
+ onProgress: (progress) => {
199
+ console.log(`Step ${progress.currentStep}/${progress.totalSteps}`)
200
+ console.log(`${progress.message} (${progress.percentage}%)`)
201
+ updateProgressBar(progress.percentage)
202
+ },
203
+ onStatusChange: (status) => {
204
+ switch (status) {
205
+ case OperationStatus.QUEUED:
206
+ showMessage('Operation queued...')
207
+ break
208
+ case OperationStatus.RUNNING:
209
+ showMessage('Processing...')
210
+ break
211
+ case OperationStatus.COMPLETED:
212
+ showMessage('Success!')
213
+ break
214
+ case OperationStatus.FAILED:
215
+ showMessage('Operation failed')
216
+ break
217
+ }
218
+ },
219
+ maxWaitTime: 300000, // 5 minutes max wait
220
+ })
221
+
222
+ if (result.status === OperationStatus.COMPLETED) {
223
+ processResults(result.data)
224
+ }
225
+ ```
226
+
227
+ ### Progress Tracking Patterns
228
+
229
+ ```typescript
230
+ // Create a reusable progress tracker
231
+ class ProgressTracker {
232
+ private startTime = Date.now()
233
+ private lastUpdate = Date.now()
234
+
235
+ onProgress = (progress: OperationProgress) => {
236
+ const elapsed = Date.now() - this.startTime
237
+ const rate = progress.rowsProcessed / (elapsed / 1000)
238
+ const eta = (progress.totalRows - progress.rowsProcessed) / rate
239
+
240
+ console.log(`Processing: ${progress.rowsProcessed}/${progress.totalRows} rows`)
241
+ console.log(`Rate: ${rate.toFixed(0)} rows/sec`)
242
+ console.log(`ETA: ${this.formatDuration(eta * 1000)}`)
243
+
244
+ // Update UI
245
+ this.updateUI(progress)
246
+ }
247
+
248
+ private formatDuration(ms: number): string {
249
+ const seconds = Math.floor(ms / 1000)
250
+ const minutes = Math.floor(seconds / 60)
251
+ const hours = Math.floor(minutes / 60)
252
+
253
+ if (hours > 0) return `${hours}h ${minutes % 60}m`
254
+ if (minutes > 0) return `${minutes}m ${seconds % 60}s`
255
+ return `${seconds}s`
256
+ }
257
+
258
+ private updateUI(progress: OperationProgress) {
259
+ // Update your UI components
260
+ document.querySelector('#progress-bar')?.setAttribute('value', progress.percentage.toString())
261
+ document.querySelector('#progress-text')?.textContent =
262
+ `${progress.message} (${progress.percentage}%)`
263
+ }
264
+ }
265
+
266
+ // Use the tracker
267
+ const tracker = new ProgressTracker()
268
+ await operationClient.monitor('operation-id', {
269
+ onProgress: tracker.onProgress,
270
+ })
271
+ ```
272
+
273
+ ## ⚛️ React Integration
274
+
275
+ ### useSSE Hook
276
+
277
+ ```typescript
278
+ import { useSSE } from '@robosystems/client/extensions/hooks'
279
+
280
+ function OperationMonitor({ operationId }: { operationId: string }) {
281
+ const {
282
+ data,
283
+ progress,
284
+ status,
285
+ error,
286
+ isConnected
287
+ } = useSSE(operationId, {
288
+ onProgress: (p) => console.log('Progress:', p),
289
+ onDataChunk: (chunk) => console.log('Chunk:', chunk),
290
+ })
291
+
292
+ if (error) return <div>Error: {error.message}</div>
293
+ if (!isConnected) return <div>Connecting...</div>
294
+
295
+ return (
296
+ <div>
297
+ <h3>Operation Status: {status}</h3>
298
+ {progress && (
299
+ <div>
300
+ <progress value={progress.percentage} max="100" />
301
+ <p>{progress.message}</p>
302
+ </div>
303
+ )}
304
+ {data && (
305
+ <div>
306
+ <h4>Results:</h4>
307
+ <pre>{JSON.stringify(data, null, 2)}</pre>
308
+ </div>
309
+ )}
310
+ </div>
311
+ )
312
+ }
313
+ ```
314
+
315
+ ### useQueryWithSSE Hook
316
+
317
+ ```typescript
318
+ import { useQueryWithSSE } from '@robosystems/client/extensions/hooks'
319
+
320
+ function QueryRunner() {
321
+ const {
322
+ execute,
323
+ loading,
324
+ data,
325
+ error,
326
+ progress,
327
+ queuePosition
328
+ } = useQueryWithSSE('your-graph-id')
329
+
330
+ const runQuery = async () => {
331
+ const result = await execute(
332
+ 'MATCH (c:Company) RETURN c.name, c.revenue LIMIT 100'
333
+ )
334
+ console.log('Query completed:', result)
335
+ }
336
+
337
+ return (
338
+ <div>
339
+ <button onClick={runQuery} disabled={loading}>
340
+ Run Query
341
+ </button>
342
+
343
+ {loading && (
344
+ <div>
345
+ {queuePosition > 0 && <p>Queue position: {queuePosition}</p>}
346
+ {progress && <p>Progress: {progress.percentage}%</p>}
347
+ </div>
348
+ )}
349
+
350
+ {error && <div className="error">{error.message}</div>}
351
+
352
+ {data && (
353
+ <table>
354
+ <tbody>
355
+ {data.rows.map((row, i) => (
356
+ <tr key={i}>
357
+ <td>{row['c.name']}</td>
358
+ <td>${row['c.revenue'].toLocaleString()}</td>
359
+ </tr>
360
+ ))}
361
+ </tbody>
362
+ </table>
363
+ )}
364
+ </div>
365
+ )
366
+ }
367
+ ```
368
+
369
+ ## 🛡️ Error Handling & Resilience
370
+
371
+ ### Circuit Breaker Pattern
372
+
373
+ The SSE system includes automatic circuit breaker protection:
374
+
375
+ ```typescript
376
+ // The circuit breaker automatically opens after 3 Redis failures
377
+ // It will close again after a cooldown period
378
+
379
+ sseClient.on('circuit_breaker_open', () => {
380
+ console.log('SSE circuit breaker opened - falling back to polling')
381
+ // Automatically degrades to polling
382
+ })
383
+
384
+ sseClient.on('circuit_breaker_closed', () => {
385
+ console.log('SSE circuit breaker closed - resuming streaming')
386
+ // Automatically resumes SSE when healthy
387
+ })
388
+ ```
389
+
390
+ ### Graceful Degradation
391
+
392
+ ```typescript
393
+ import { QueryClient, FallbackStrategy } from '@robosystems/client/extensions'
394
+
395
+ const queryClient = new QueryClient({
396
+ baseUrl: 'https://api.robosystems.ai',
397
+ fallbackStrategy: FallbackStrategy.AUTO, // Automatically choose best strategy
398
+ })
399
+
400
+ // Automatically uses best available method:
401
+ // 1. SSE streaming (preferred)
402
+ // 2. NDJSON streaming (if SSE unavailable)
403
+ // 3. Polling (if streaming unavailable)
404
+ // 4. Direct response (for small queries)
405
+
406
+ const result = await queryClient.execute('graph-id', 'MATCH (n) RETURN n', {
407
+ preferStreaming: true, // Hint to prefer streaming
408
+ onFallback: (from, to) => {
409
+ console.log(`Falling back from ${from} to ${to}`)
410
+ },
411
+ })
412
+ ```
413
+
414
+ ### Connection Pool Management
415
+
416
+ ```typescript
417
+ // SDK automatically manages SSE connection pooling
418
+ const config = {
419
+ maxConnections: 5, // Per-user limit enforced by server
420
+ connectionTimeout: 10000, // 10 second timeout
421
+ poolStrategy: 'FIFO', // First-in-first-out recycling
422
+ }
423
+
424
+ // Connections are automatically recycled when limits are reached
425
+ const operations = [
426
+ 'operation-1',
427
+ 'operation-2',
428
+ 'operation-3',
429
+ 'operation-4',
430
+ 'operation-5',
431
+ 'operation-6', // Will recycle oldest connection
432
+ ]
433
+
434
+ // Monitor connection pool status
435
+ sseClient.on('connection_recycled', ({ old, new }) => {
436
+ console.log(`Recycled connection from ${old} to ${new}`)
437
+ })
438
+ ```
439
+
440
+ ## 🔧 Configuration
441
+
442
+ ### Environment Variables
443
+
444
+ ```bash
445
+ # API Configuration
446
+ NEXT_PUBLIC_ROBOSYSTEMS_API_URL=https://api.robosystems.ai
447
+ ROBOSYSTEMS_API_KEY=your-api-key
448
+
449
+ # SSE Configuration
450
+ NEXT_PUBLIC_SSE_MAX_RETRIES=5
451
+ NEXT_PUBLIC_SSE_RETRY_DELAY=1000
452
+ NEXT_PUBLIC_SSE_HEARTBEAT_INTERVAL=30000
453
+
454
+ # Feature Flags
455
+ NEXT_PUBLIC_ENABLE_SSE=true
456
+ NEXT_PUBLIC_PREFER_STREAMING=true
457
+ ```
458
+
459
+ ### Custom Configuration
460
+
461
+ ```typescript
462
+ import { createSSEClient } from '@robosystems/client/extensions'
463
+
464
+ const sseClient = createSSEClient({
465
+ // API Configuration
466
+ baseUrl: process.env.NEXT_PUBLIC_ROBOSYSTEMS_API_URL,
467
+
468
+ // Authentication
469
+ credentials: 'include', // For cookies
470
+ headers: {
471
+ 'X-API-Key': process.env.ROBOSYSTEMS_API_KEY,
472
+ },
473
+
474
+ // Connection Settings
475
+ maxRetries: 5,
476
+ retryDelay: 1000,
477
+ heartbeatInterval: 30000,
478
+
479
+ // Advanced Options
480
+ eventSourceOptions: {
481
+ withCredentials: true,
482
+ },
483
+ })
484
+ ```
485
+
486
+ ## 📊 Performance Optimization
487
+
488
+ ### Stream Processing for Large Datasets
489
+
490
+ ```typescript
491
+ import { StreamProcessor } from '@robosystems/client/extensions'
492
+
493
+ const processor = new StreamProcessor({
494
+ batchSize: 1000,
495
+ concurrency: 3,
496
+ })
497
+
498
+ // Process large query results efficiently
499
+ await processor.processStream('your-graph-id', 'MATCH (t:Transaction) RETURN t', {
500
+ onBatch: async (batch) => {
501
+ // Process batch of 1000 rows
502
+ await saveToDB(batch)
503
+ console.log(`Processed ${batch.length} transactions`)
504
+ },
505
+ onProgress: (processed, total) => {
506
+ const percentage = (processed / total) * 100
507
+ console.log(`Progress: ${percentage.toFixed(2)}%`)
508
+ },
509
+ })
510
+ ```
511
+
512
+ ### Caching with SSE Updates
513
+
514
+ ```typescript
515
+ import { CachedQueryClient } from '@robosystems/client/extensions'
516
+
517
+ const cachedClient = new CachedQueryClient({
518
+ ttl: 300000, // 5 minute cache
519
+ maxSize: 100, // Cache up to 100 queries
520
+ })
521
+
522
+ // First call hits the API
523
+ const result1 = await cachedClient.execute('graph-id', 'MATCH (n) RETURN COUNT(n)')
524
+
525
+ // Second call returns from cache
526
+ const result2 = await cachedClient.execute('graph-id', 'MATCH (n) RETURN COUNT(n)')
527
+
528
+ // SSE updates automatically invalidate relevant cache entries
529
+ cachedClient.on('cache_invalidated', (query) => {
530
+ console.log('Cache invalidated for:', query)
531
+ })
532
+ ```
533
+
534
+ ## 🧪 Testing
535
+
536
+ ### Mock SSE for Testing
537
+
538
+ ```typescript
539
+ import { MockSSEClient } from '@robosystems/client/extensions/testing'
540
+
541
+ describe('SSE Integration', () => {
542
+ it('should handle progress events', async () => {
543
+ const mockClient = new MockSSEClient()
544
+
545
+ // Set up mock events
546
+ mockClient.simulateEvents([
547
+ { event: EventType.OPERATION_STARTED, data: { message: 'Starting' } },
548
+ { event: EventType.OPERATION_PROGRESS, data: { percentage: 50 } },
549
+ { event: EventType.OPERATION_COMPLETED, data: { result: 'Success' } },
550
+ ])
551
+
552
+ // Test your component
553
+ const { getByText } = render(
554
+ <OperationMonitor
555
+ operationId="test-123"
556
+ sseClient={mockClient}
557
+ />
558
+ )
559
+
560
+ await waitFor(() => {
561
+ expect(getByText('Starting')).toBeInTheDocument()
562
+ expect(getByText('50%')).toBeInTheDocument()
563
+ expect(getByText('Success')).toBeInTheDocument()
564
+ })
565
+ })
566
+ })
567
+ ```
568
+
569
+ ## 📚 API Reference
570
+
571
+ ### Core Classes
572
+
573
+ - **`SSEClient`** - Server-Sent Events client with auto-reconnection
574
+ - **`QueryClient`** - Enhanced query execution with SSE support
575
+ - **`OperationClient`** - Long-running operation monitoring
576
+ - **`StreamProcessor`** - Efficient stream processing for large datasets
577
+
578
+ ### Event Types
579
+
580
+ - **`EventType`** - Enum of all supported SSE event types
581
+ - **`SSEEvent`** - Typed SSE event structure
582
+ - **`OperationProgress`** - Progress update structure
583
+ - **`OperationStatus`** - Operation status enum
584
+
585
+ ### React Hooks
586
+
587
+ - **`useSSE`** - Hook for SSE connection management
588
+ - **`useQueryWithSSE`** - Hook for queries with progress
589
+ - **`useOperation`** - Hook for operation monitoring
590
+
591
+ ### Utilities
592
+
593
+ - **`createSSEClient`** - Factory for configured SSE clients
594
+ - **`formatDuration`** - Human-readable duration formatting
595
+ - **`parseSSEEvent`** - SSE event parsing utility
596
+
597
+ ## 🐛 Troubleshooting
598
+
599
+ ### Common Issues
600
+
601
+ **Rate Limit Errors (429)**
602
+
603
+ ```typescript
604
+ // Handle rate limiting gracefully
605
+ if (error.status === 429) {
606
+ const retryAfter = error.headers['retry-after'] || 60
607
+ console.log(`Rate limited. Retry after ${retryAfter} seconds`)
608
+
609
+ // Use exponential backoff
610
+ await sleep(retryAfter * 1000)
611
+ await retry()
612
+ }
613
+ ```
614
+
615
+ **Connection Drops**
616
+
617
+ ```typescript
618
+ // SSE automatically reconnects, but you can handle it manually
619
+ sseClient.on('disconnected', () => {
620
+ showNotification('Connection lost. Reconnecting...')
621
+ })
622
+
623
+ sseClient.on('connected', () => {
624
+ showNotification('Connection restored')
625
+ })
626
+ ```
627
+
628
+ **Circuit Breaker Open (503)**
629
+
630
+ ```typescript
631
+ // SSE system temporarily disabled
632
+ if (error.status === 503) {
633
+ console.log('SSE system unavailable - using fallback')
634
+ // Automatically falls back to polling
635
+ }
636
+ ```
637
+
638
+ ### Debug Mode
639
+
640
+ ```typescript
641
+ // Enable debug logging
642
+ const sseClient = new SSEClient({
643
+ baseUrl: 'https://api.robosystems.ai',
644
+ debug: true, // Enables detailed logging
645
+ })
646
+
647
+ // Monitor all events
648
+ sseClient.on('*', (event, data) => {
649
+ console.log(`[SSE Debug] ${event}:`, data)
650
+ })
651
+ ```
652
+
653
+ ## 📄 License
654
+
655
+ MIT License - see [LICENSE](../../LICENSE) file for details.
656
+
657
+ ## 🤝 Contributing
658
+
659
+ See the [Contributing Guide](../../CONTRIBUTING.md) for development setup and guidelines.
660
+
661
+ ## 📞 Support
662
+
663
+ - **Documentation**: [docs.robosystems.ai](https://docs.robosystems.ai)
664
+ - **API Reference**: [api.robosystems.ai/docs](https://api.robosystems.ai/docs)
665
+ - **Discord**: [Join our community](https://discord.gg/robosystems)
666
+ - **Issues**: [GitHub Issues](https://github.com/robosystems/sdk/issues)
667
+
668
+ ---
669
+
670
+ **RoboSystems Typescript Client Extensions** - Production-ready SSE streaming and real-time monitoring for financial knowledge graphs.
671
+
672
+ _Built with ❤️ by the RoboSystems team_
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Core SSE (Server-Sent Events) client for RoboSystems API
3
+ * Provides automatic reconnection, event replay, and type-safe event handling
4
+ */
5
+ export interface SSEConfig {
6
+ baseUrl: string;
7
+ credentials?: 'include' | 'same-origin' | 'omit';
8
+ headers?: Record<string, string>;
9
+ maxRetries?: number;
10
+ retryDelay?: number;
11
+ heartbeatInterval?: number;
12
+ }
13
+ export interface SSEEvent {
14
+ event: string;
15
+ data: any;
16
+ id?: string;
17
+ retry?: number;
18
+ timestamp: Date;
19
+ }
20
+ export declare enum EventType {
21
+ OPERATION_STARTED = "operation_started",
22
+ OPERATION_PROGRESS = "operation_progress",
23
+ OPERATION_COMPLETED = "operation_completed",
24
+ OPERATION_ERROR = "operation_error",
25
+ OPERATION_CANCELLED = "operation_cancelled",
26
+ DATA_CHUNK = "data_chunk",
27
+ METADATA = "metadata",
28
+ HEARTBEAT = "heartbeat",
29
+ QUEUE_UPDATE = "queue_update"
30
+ }
31
+ export declare class SSEClient {
32
+ private config;
33
+ private eventSource?;
34
+ private reconnectAttempts;
35
+ private lastEventId?;
36
+ private closed;
37
+ private listeners;
38
+ constructor(config: SSEConfig);
39
+ connect(operationId: string, fromSequence?: number): Promise<void>;
40
+ private handleMessage;
41
+ private handleTypedEvent;
42
+ private handleError;
43
+ on(event: string, listener: (data: any) => void): void;
44
+ off(event: string, listener: (data: any) => void): void;
45
+ private emit;
46
+ close(): void;
47
+ isConnected(): boolean;
48
+ }