@robosystems/client 0.2.48 → 0.3.0

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 (190) hide show
  1. package/extensions/InvestorClient.d.ts +91 -0
  2. package/extensions/InvestorClient.js +223 -0
  3. package/extensions/InvestorClient.ts +501 -0
  4. package/extensions/LedgerClient.d.ts +213 -165
  5. package/extensions/LedgerClient.js +315 -393
  6. package/extensions/LedgerClient.ts +887 -564
  7. package/extensions/ReportClient.d.ts +77 -115
  8. package/extensions/ReportClient.js +124 -211
  9. package/extensions/ReportClient.ts +298 -358
  10. package/extensions/config.js +1 -1
  11. package/extensions/config.ts +1 -1
  12. package/extensions/graphql/client.d.ts +46 -0
  13. package/extensions/graphql/client.js +75 -0
  14. package/extensions/graphql/client.ts +82 -0
  15. package/extensions/graphql/generated/graphql.d.ts +1786 -0
  16. package/extensions/graphql/generated/graphql.js +2671 -0
  17. package/extensions/graphql/generated/graphql.ts +4491 -0
  18. package/extensions/graphql/queries/investor/holdings.d.ts +8 -0
  19. package/extensions/graphql/queries/investor/holdings.js +36 -0
  20. package/extensions/graphql/queries/investor/holdings.ts +34 -0
  21. package/extensions/graphql/queries/investor/portfolio.d.ts +4 -0
  22. package/extensions/graphql/queries/investor/portfolio.js +21 -0
  23. package/extensions/graphql/queries/investor/portfolio.ts +19 -0
  24. package/extensions/graphql/queries/investor/portfolios.d.ts +4 -0
  25. package/extensions/graphql/queries/investor/portfolios.js +29 -0
  26. package/extensions/graphql/queries/investor/portfolios.ts +27 -0
  27. package/extensions/graphql/queries/investor/position.d.ts +4 -0
  28. package/extensions/graphql/queries/investor/position.js +33 -0
  29. package/extensions/graphql/queries/investor/position.ts +31 -0
  30. package/extensions/graphql/queries/investor/positions.d.ts +8 -0
  31. package/extensions/graphql/queries/investor/positions.js +57 -0
  32. package/extensions/graphql/queries/investor/positions.ts +55 -0
  33. package/extensions/graphql/queries/investor/securities.d.ts +8 -0
  34. package/extensions/graphql/queries/investor/securities.js +50 -0
  35. package/extensions/graphql/queries/investor/securities.ts +48 -0
  36. package/extensions/graphql/queries/investor/security.d.ts +4 -0
  37. package/extensions/graphql/queries/investor/security.js +26 -0
  38. package/extensions/graphql/queries/investor/security.ts +24 -0
  39. package/extensions/graphql/queries/ledger/accountRollups.d.ts +7 -0
  40. package/extensions/graphql/queries/ledger/accountRollups.js +36 -0
  41. package/extensions/graphql/queries/ledger/accountRollups.ts +34 -0
  42. package/extensions/graphql/queries/ledger/accountTree.d.ts +11 -0
  43. package/extensions/graphql/queries/ledger/accountTree.js +61 -0
  44. package/extensions/graphql/queries/ledger/accountTree.ts +59 -0
  45. package/extensions/graphql/queries/ledger/accounts.d.ts +8 -0
  46. package/extensions/graphql/queries/ledger/accounts.js +45 -0
  47. package/extensions/graphql/queries/ledger/accounts.ts +43 -0
  48. package/extensions/graphql/queries/ledger/closingBookStructures.d.ts +6 -0
  49. package/extensions/graphql/queries/ledger/closingBookStructures.js +27 -0
  50. package/extensions/graphql/queries/ledger/closingBookStructures.ts +25 -0
  51. package/extensions/graphql/queries/ledger/elements.d.ts +6 -0
  52. package/extensions/graphql/queries/ledger/elements.js +56 -0
  53. package/extensions/graphql/queries/ledger/elements.ts +54 -0
  54. package/extensions/graphql/queries/ledger/entities.d.ts +7 -0
  55. package/extensions/graphql/queries/ledger/entities.js +31 -0
  56. package/extensions/graphql/queries/ledger/entities.ts +29 -0
  57. package/extensions/graphql/queries/ledger/entity.d.ts +14 -0
  58. package/extensions/graphql/queries/ledger/entity.js +55 -0
  59. package/extensions/graphql/queries/ledger/entity.ts +54 -0
  60. package/extensions/graphql/queries/ledger/fiscalCalendar.d.ts +8 -0
  61. package/extensions/graphql/queries/ledger/fiscalCalendar.js +35 -0
  62. package/extensions/graphql/queries/ledger/fiscalCalendar.ts +33 -0
  63. package/extensions/graphql/queries/ledger/mappedTrialBalance.d.ts +9 -0
  64. package/extensions/graphql/queries/ledger/mappedTrialBalance.js +29 -0
  65. package/extensions/graphql/queries/ledger/mappedTrialBalance.ts +27 -0
  66. package/extensions/graphql/queries/ledger/mapping.d.ts +5 -0
  67. package/extensions/graphql/queries/ledger/mapping.js +35 -0
  68. package/extensions/graphql/queries/ledger/mapping.ts +33 -0
  69. package/extensions/graphql/queries/ledger/mappingCoverage.d.ts +5 -0
  70. package/extensions/graphql/queries/ledger/mappingCoverage.js +22 -0
  71. package/extensions/graphql/queries/ledger/mappingCoverage.ts +20 -0
  72. package/extensions/graphql/queries/ledger/mappings.d.ts +6 -0
  73. package/extensions/graphql/queries/ledger/mappings.js +23 -0
  74. package/extensions/graphql/queries/ledger/mappings.ts +21 -0
  75. package/extensions/graphql/queries/ledger/periodCloseStatus.d.ts +6 -0
  76. package/extensions/graphql/queries/ledger/periodCloseStatus.js +29 -0
  77. package/extensions/graphql/queries/ledger/periodCloseStatus.ts +27 -0
  78. package/extensions/graphql/queries/ledger/periodDrafts.d.ts +8 -0
  79. package/extensions/graphql/queries/ledger/periodDrafts.js +45 -0
  80. package/extensions/graphql/queries/ledger/periodDrafts.ts +43 -0
  81. package/extensions/graphql/queries/ledger/publishList.d.ts +5 -0
  82. package/extensions/graphql/queries/ledger/publishList.js +29 -0
  83. package/extensions/graphql/queries/ledger/publishList.ts +27 -0
  84. package/extensions/graphql/queries/ledger/publishLists.d.ts +5 -0
  85. package/extensions/graphql/queries/ledger/publishLists.js +29 -0
  86. package/extensions/graphql/queries/ledger/publishLists.ts +27 -0
  87. package/extensions/graphql/queries/ledger/report.d.ts +5 -0
  88. package/extensions/graphql/queries/ledger/report.js +40 -0
  89. package/extensions/graphql/queries/ledger/report.ts +38 -0
  90. package/extensions/graphql/queries/ledger/reportingTaxonomy.d.ts +6 -0
  91. package/extensions/graphql/queries/ledger/reportingTaxonomy.js +27 -0
  92. package/extensions/graphql/queries/ledger/reportingTaxonomy.ts +25 -0
  93. package/extensions/graphql/queries/ledger/reports.d.ts +8 -0
  94. package/extensions/graphql/queries/ledger/reports.js +45 -0
  95. package/extensions/graphql/queries/ledger/reports.ts +43 -0
  96. package/extensions/graphql/queries/ledger/scheduleFacts.d.ts +7 -0
  97. package/extensions/graphql/queries/ledger/scheduleFacts.js +24 -0
  98. package/extensions/graphql/queries/ledger/scheduleFacts.ts +22 -0
  99. package/extensions/graphql/queries/ledger/schedules.d.ts +6 -0
  100. package/extensions/graphql/queries/ledger/schedules.js +24 -0
  101. package/extensions/graphql/queries/ledger/schedules.ts +22 -0
  102. package/extensions/graphql/queries/ledger/statement.d.ts +9 -0
  103. package/extensions/graphql/queries/ledger/statement.js +43 -0
  104. package/extensions/graphql/queries/ledger/statement.ts +41 -0
  105. package/extensions/graphql/queries/ledger/structures.d.ts +5 -0
  106. package/extensions/graphql/queries/ledger/structures.js +22 -0
  107. package/extensions/graphql/queries/ledger/structures.ts +20 -0
  108. package/extensions/graphql/queries/ledger/summary.d.ts +7 -0
  109. package/extensions/graphql/queries/ledger/summary.js +25 -0
  110. package/extensions/graphql/queries/ledger/summary.ts +23 -0
  111. package/extensions/graphql/queries/ledger/taxonomies.d.ts +5 -0
  112. package/extensions/graphql/queries/ledger/taxonomies.js +28 -0
  113. package/extensions/graphql/queries/ledger/taxonomies.ts +26 -0
  114. package/extensions/graphql/queries/ledger/transaction.d.ts +6 -0
  115. package/extensions/graphql/queries/ledger/transaction.js +49 -0
  116. package/extensions/graphql/queries/ledger/transaction.ts +47 -0
  117. package/extensions/graphql/queries/ledger/transactions.d.ts +7 -0
  118. package/extensions/graphql/queries/ledger/transactions.js +49 -0
  119. package/extensions/graphql/queries/ledger/transactions.ts +47 -0
  120. package/extensions/graphql/queries/ledger/trialBalance.d.ts +7 -0
  121. package/extensions/graphql/queries/ledger/trialBalance.js +28 -0
  122. package/extensions/graphql/queries/ledger/trialBalance.ts +26 -0
  123. package/extensions/graphql/queries/ledger/unmappedElements.d.ts +8 -0
  124. package/extensions/graphql/queries/ledger/unmappedElements.js +29 -0
  125. package/extensions/graphql/queries/ledger/unmappedElements.ts +27 -0
  126. package/extensions/hooks.d.ts +1 -1
  127. package/extensions/index.d.ts +5 -1
  128. package/extensions/index.js +13 -1
  129. package/extensions/index.ts +14 -0
  130. package/index.ts +2 -2
  131. package/package.json +14 -5
  132. package/sdk/index.d.ts +2 -2
  133. package/sdk/index.js +38 -65
  134. package/sdk/index.ts +2 -2
  135. package/sdk/sdk.gen.d.ts +101 -220
  136. package/sdk/sdk.gen.js +251 -445
  137. package/sdk/sdk.gen.ts +216 -409
  138. package/sdk/types.gen.d.ts +4586 -7045
  139. package/sdk/types.gen.ts +4702 -7334
  140. package/sdk.gen.d.ts +101 -220
  141. package/sdk.gen.js +251 -445
  142. package/sdk.gen.ts +216 -409
  143. package/types.gen.d.ts +4586 -7045
  144. package/types.gen.ts +4702 -7334
  145. package/extensions/AgentClient.test.ts +0 -403
  146. package/extensions/LedgerClient.test.ts +0 -1138
  147. package/extensions/OperationClient.test.ts +0 -365
  148. package/extensions/QueryClient.test.ts +0 -432
  149. package/extensions/ReportClient.test.ts +0 -828
  150. package/extensions/SSEClient.test.ts +0 -375
  151. package/extensions/config.test.ts +0 -199
  152. package/extensions/hooks.test.ts +0 -373
  153. package/extensions/index.test.ts +0 -420
  154. package/sdk-extensions/AgentClient.d.ts +0 -82
  155. package/sdk-extensions/AgentClient.js +0 -218
  156. package/sdk-extensions/AgentClient.test.ts +0 -403
  157. package/sdk-extensions/AgentClient.ts +0 -321
  158. package/sdk-extensions/LedgerClient.d.ts +0 -242
  159. package/sdk-extensions/LedgerClient.js +0 -496
  160. package/sdk-extensions/LedgerClient.test.ts +0 -1138
  161. package/sdk-extensions/LedgerClient.ts +0 -800
  162. package/sdk-extensions/OperationClient.d.ts +0 -65
  163. package/sdk-extensions/OperationClient.js +0 -251
  164. package/sdk-extensions/OperationClient.test.ts +0 -365
  165. package/sdk-extensions/OperationClient.ts +0 -324
  166. package/sdk-extensions/QueryClient.d.ts +0 -52
  167. package/sdk-extensions/QueryClient.js +0 -313
  168. package/sdk-extensions/QueryClient.test.ts +0 -432
  169. package/sdk-extensions/QueryClient.ts +0 -420
  170. package/sdk-extensions/README.md +0 -901
  171. package/sdk-extensions/ReportClient.d.ts +0 -151
  172. package/sdk-extensions/ReportClient.js +0 -278
  173. package/sdk-extensions/ReportClient.test.ts +0 -828
  174. package/sdk-extensions/ReportClient.ts +0 -486
  175. package/sdk-extensions/SSEClient.d.ts +0 -62
  176. package/sdk-extensions/SSEClient.js +0 -154
  177. package/sdk-extensions/SSEClient.test.ts +0 -375
  178. package/sdk-extensions/SSEClient.ts +0 -210
  179. package/sdk-extensions/config.d.ts +0 -57
  180. package/sdk-extensions/config.js +0 -152
  181. package/sdk-extensions/config.test.ts +0 -199
  182. package/sdk-extensions/config.ts +0 -175
  183. package/sdk-extensions/hooks.d.ts +0 -110
  184. package/sdk-extensions/hooks.js +0 -384
  185. package/sdk-extensions/hooks.test.ts +0 -373
  186. package/sdk-extensions/hooks.ts +0 -459
  187. package/sdk-extensions/index.d.ts +0 -63
  188. package/sdk-extensions/index.js +0 -164
  189. package/sdk-extensions/index.test.ts +0 -420
  190. package/sdk-extensions/index.ts +0 -203
@@ -1,901 +0,0 @@
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
- - **Data Copy Operations** with S3 import and real-time progress tracking
15
- - **Operation Monitoring** for long-running tasks with real-time updates
16
- - **Connection Management** with rate limiting and circuit breaker patterns
17
- - **React Hooks** for seamless UI integration
18
- - **Full TypeScript Support** with comprehensive type definitions
19
-
20
- ## Quick Start
21
-
22
- ### Installation
23
-
24
- The extensions are included with the main SDK:
25
-
26
- ```bash
27
- npm install @robosystems/client
28
- # or
29
- yarn add @robosystems/client
30
- # or
31
- pnpm add @robosystems/client
32
- ```
33
-
34
- ### Basic SSE Usage
35
-
36
- ```typescript
37
- import { SSEClient, EventType } from '@robosystems/client/extensions'
38
-
39
- // Initialize SSE client
40
- const sseClient = new SSEClient({
41
- baseUrl: 'https://api.robosystems.ai',
42
- credentials: 'include', // For cookie auth
43
- maxRetries: 5,
44
- retryDelay: 1000,
45
- })
46
-
47
- // Connect to operation stream
48
- await sseClient.connect('operation-id-123')
49
-
50
- // Listen for events
51
- sseClient.on(EventType.OPERATION_PROGRESS, (data) => {
52
- console.log(`Progress: ${data.message} (${data.percentage}%)`)
53
- })
54
-
55
- sseClient.on(EventType.DATA_CHUNK, (data) => {
56
- console.log(`Received ${data.rows.length} rows`)
57
- processRows(data.rows)
58
- })
59
-
60
- sseClient.on(EventType.OPERATION_COMPLETED, (data) => {
61
- console.log('Operation completed:', data.result)
62
- })
63
-
64
- // Clean up when done
65
- sseClient.close()
66
- ```
67
-
68
- ### Query Execution with Progress Monitoring
69
-
70
- ```typescript
71
- import { QueryClient } from '@robosystems/client/extensions'
72
-
73
- const queryClient = new QueryClient({
74
- baseUrl: 'https://api.robosystems.ai',
75
- apiKey: 'your-api-key',
76
- })
77
-
78
- // Execute query with automatic SSE monitoring
79
- const result = await queryClient.executeWithProgress(
80
- 'your-graph-id',
81
- 'MATCH (c:Company) RETURN c.name, c.revenue ORDER BY c.revenue DESC',
82
- {
83
- onProgress: (progress) => {
84
- console.log(`${progress.current}/${progress.total} rows processed`)
85
- },
86
- onQueueUpdate: (position, estimatedWait) => {
87
- console.log(`Queue position: ${position}, ETA: ${estimatedWait}s`)
88
- },
89
- }
90
- )
91
-
92
- console.log(`Query completed with ${result.rowCount} results`)
93
- ```
94
-
95
- ### Table Ingestion with Progress Monitoring
96
-
97
- ```typescript
98
- import { TableIngestClient } from '@robosystems/client/extensions'
99
-
100
- const tableClient = new TableIngestClient({
101
- baseUrl: 'https://api.robosystems.ai',
102
- headers: { 'X-API-Key': 'your-api-key' },
103
- })
104
-
105
- // Upload Parquet file with real-time progress
106
- import { readFileSync } from 'fs'
107
-
108
- const fileBuffer = readFileSync('data/companies.parquet')
109
- const result = await tableClient.uploadParquetFile(
110
- 'your-graph-id',
111
- 'Company',
112
- Buffer.from(fileBuffer),
113
- {
114
- onProgress: (message) => {
115
- console.log(`Upload progress: ${message}`)
116
- },
117
- }
118
- )
119
-
120
- // Check results
121
- if (result.success) {
122
- console.log(`Successfully uploaded ${result.rowCount} rows to ${result.tableName}`)
123
- console.log(`File size: ${(result.fileSize / 1024 / 1024).toFixed(2)} MB`)
124
-
125
- // Ingest the table into the graph
126
- const ingestResult = await tableClient.ingestAllTables('your-graph-id', {
127
- ignoreErrors: true,
128
- rebuild: false,
129
- onProgress: (msg) => console.log(`Ingest: ${msg}`),
130
- })
131
-
132
- if (ingestResult.success) {
133
- console.log(`Ingestion started. Operation ID: ${ingestResult.operationId}`)
134
- }
135
- } else {
136
- console.error(`Upload failed: ${result.error}`)
137
- }
138
- ```
139
-
140
- ## SSE Event Types
141
-
142
- The SDK supports all RoboSystems SSE event types:
143
-
144
- ```typescript
145
- enum EventType {
146
- // Operation lifecycle
147
- OPERATION_STARTED = 'operation_started',
148
- OPERATION_PROGRESS = 'operation_progress',
149
- OPERATION_COMPLETED = 'operation_completed',
150
- OPERATION_ERROR = 'operation_error',
151
- OPERATION_CANCELLED = 'operation_cancelled',
152
-
153
- // Data streaming
154
- DATA_CHUNK = 'data_chunk',
155
- METADATA = 'metadata',
156
-
157
- // Queue management
158
- QUEUE_UPDATE = 'queue_update',
159
-
160
- // Connection health
161
- HEARTBEAT = 'heartbeat',
162
- }
163
- ```
164
-
165
- ## Advanced SSE Features
166
-
167
- ### Automatic Reconnection
168
-
169
- The SSE client automatically reconnects on connection loss with exponential backoff:
170
-
171
- ```typescript
172
- const sseClient = new SSEClient({
173
- baseUrl: 'https://api.robosystems.ai',
174
- maxRetries: 5, // Maximum reconnection attempts
175
- retryDelay: 1000, // Initial retry delay (ms)
176
- heartbeatInterval: 30000, // Heartbeat check interval
177
- })
178
-
179
- // Monitor reconnection attempts
180
- sseClient.on('reconnecting', ({ attempt, delay, lastEventId }) => {
181
- console.log(`Reconnecting (attempt ${attempt}) in ${delay}ms...`)
182
- console.log(`Resuming from event ${lastEventId}`)
183
- })
184
-
185
- sseClient.on('max_retries_exceeded', (error) => {
186
- console.error('Failed to reconnect after maximum attempts')
187
- // Fallback to polling or show error to user
188
- })
189
- ```
190
-
191
- ### Event Replay
192
-
193
- SSE automatically resumes from the last received event after reconnection:
194
-
195
- ```typescript
196
- // Connect with specific starting sequence
197
- await sseClient.connect('operation-id', fromSequence)
198
-
199
- // The client tracks lastEventId automatically
200
- sseClient.on('event', (event) => {
201
- console.log(`Event ${event.id}: ${event.event}`)
202
- // Events are guaranteed to be in sequence
203
- })
204
- ```
205
-
206
- ### Rate Limiting & Connection Management
207
-
208
- The SDK respects server-side rate limits:
209
-
210
- - **Maximum 5 concurrent SSE connections per user**
211
- - **10 new connections per minute rate limit**
212
- - **Automatic circuit breaker for Redis failures**
213
-
214
- ```typescript
215
- // Handle rate limiting gracefully
216
- try {
217
- await sseClient.connect('operation-id')
218
- } catch (error) {
219
- if (error.status === 429) {
220
- console.log('Rate limit exceeded - falling back to polling')
221
- // Use polling fallback
222
- const result = await pollOperation('operation-id')
223
- } else if (error.status === 503) {
224
- console.log('SSE temporarily unavailable - circuit breaker open')
225
- // SSE system is degraded, use alternative method
226
- }
227
- }
228
- ```
229
-
230
- ## Table Ingestion
231
-
232
- ### TableIngestClient for Parquet File Uploads
233
-
234
- Upload Parquet files directly to staging tables with simplified API.
235
-
236
- ```typescript
237
- import { TableIngestClient } from '@robosystems/client/extensions'
238
-
239
- const tableClient = new TableIngestClient({
240
- baseUrl: 'https://api.robosystems.ai',
241
- headers: { 'X-API-Key': 'your-api-key' },
242
- })
243
-
244
- // Upload a Parquet file (Node.js with Buffer)
245
- import { readFileSync } from 'fs'
246
-
247
- const fileBuffer = readFileSync('data/entities.parquet')
248
- const result = await tableClient.uploadParquetFile('graph-id', 'Entity', Buffer.from(fileBuffer), {
249
- onProgress: (msg) => console.log(msg),
250
- })
251
-
252
- if (result.success) {
253
- console.log(`Uploaded ${result.rowCount} rows to ${result.tableName}`)
254
- } else {
255
- console.error(`Upload failed: ${result.error}`)
256
- }
257
- ```
258
-
259
- ### Upload File in Browser
260
-
261
- ```typescript
262
- // Browser with File object
263
- const handleFileUpload = async (file: File) => {
264
- const result = await tableClient.uploadParquetFile('graph-id', 'Entity', file, {
265
- onProgress: (msg) => console.log(msg),
266
- })
267
-
268
- if (result.success) {
269
- console.log(`Uploaded ${result.rowCount} rows`)
270
- }
271
- }
272
-
273
- // Usage in React component
274
- <input type="file" accept=".parquet" onChange={(e) => {
275
- const file = e.target.files?.[0]
276
- if (file) handleFileUpload(file)
277
- }} />
278
- ```
279
-
280
- ### Upload and Ingest in One Step
281
-
282
- ```typescript
283
- // Upload a file and immediately ingest it into the graph
284
- const { upload, ingest } = await tableClient.uploadAndIngest(
285
- 'graph-id',
286
- 'Entity',
287
- fileBuffer,
288
- {
289
- // Upload options
290
- onProgress: (msg) => console.log(`Upload: ${msg}`),
291
- },
292
- {
293
- // Ingest options
294
- ignoreErrors: true,
295
- rebuild: false,
296
- onProgress: (msg) => console.log(`Ingest: ${msg}`),
297
- }
298
- )
299
-
300
- if (upload.success && ingest?.success) {
301
- console.log(`Operation ID: ${ingest.operationId}`)
302
- }
303
- ```
304
-
305
- ### List Staging Tables
306
-
307
- ```typescript
308
- // List all staging tables in a graph
309
- const tables = await tableClient.listStagingTables('graph-id')
310
-
311
- tables.forEach((table) => {
312
- console.log(`Table: ${table.tableName}`)
313
- console.log(` Rows: ${table.rowCount}`)
314
- console.log(` Files: ${table.fileCount}`)
315
- console.log(` Size: ${(table.totalSizeBytes / 1024 / 1024).toFixed(2)} MB`)
316
- })
317
- ```
318
-
319
- ### Ingest All Tables
320
-
321
- ```typescript
322
- // Ingest all staging tables into the graph
323
- const result = await tableClient.ingestAllTables('graph-id', {
324
- ignoreErrors: true, // Continue on errors
325
- rebuild: false, // Don't rebuild existing data
326
- onProgress: (msg) => console.log(msg),
327
- })
328
-
329
- if (result.success) {
330
- console.log(`Ingestion started. Operation ID: ${result.operationId}`)
331
- }
332
- ```
333
-
334
- ## Operation Monitoring
335
-
336
- ### OperationClient for Long-Running Tasks
337
-
338
- ```typescript
339
- import { OperationClient, OperationStatus } from '@robosystems/client/extensions'
340
-
341
- const operationClient = new OperationClient({
342
- baseUrl: 'https://api.robosystems.ai',
343
- apiKey: 'your-api-key',
344
- })
345
-
346
- // Monitor any long-running operation
347
- const result = await operationClient.monitor('operation-id', {
348
- onProgress: (progress) => {
349
- console.log(`Step ${progress.currentStep}/${progress.totalSteps}`)
350
- console.log(`${progress.message} (${progress.percentage}%)`)
351
- updateProgressBar(progress.percentage)
352
- },
353
- onStatusChange: (status) => {
354
- switch (status) {
355
- case OperationStatus.QUEUED:
356
- showMessage('Operation queued...')
357
- break
358
- case OperationStatus.RUNNING:
359
- showMessage('Processing...')
360
- break
361
- case OperationStatus.COMPLETED:
362
- showMessage('Success!')
363
- break
364
- case OperationStatus.FAILED:
365
- showMessage('Operation failed')
366
- break
367
- }
368
- },
369
- maxWaitTime: 300000, // 5 minutes max wait
370
- })
371
-
372
- if (result.status === OperationStatus.COMPLETED) {
373
- processResults(result.data)
374
- }
375
- ```
376
-
377
- ### Progress Tracking Patterns
378
-
379
- ```typescript
380
- // Create a reusable progress tracker
381
- class ProgressTracker {
382
- private startTime = Date.now()
383
- private lastUpdate = Date.now()
384
-
385
- onProgress = (progress: OperationProgress) => {
386
- const elapsed = Date.now() - this.startTime
387
- const rate = progress.rowsProcessed / (elapsed / 1000)
388
- const eta = (progress.totalRows - progress.rowsProcessed) / rate
389
-
390
- console.log(`Processing: ${progress.rowsProcessed}/${progress.totalRows} rows`)
391
- console.log(`Rate: ${rate.toFixed(0)} rows/sec`)
392
- console.log(`ETA: ${this.formatDuration(eta * 1000)}`)
393
-
394
- // Update UI
395
- this.updateUI(progress)
396
- }
397
-
398
- private formatDuration(ms: number): string {
399
- const seconds = Math.floor(ms / 1000)
400
- const minutes = Math.floor(seconds / 60)
401
- const hours = Math.floor(minutes / 60)
402
-
403
- if (hours > 0) return `${hours}h ${minutes % 60}m`
404
- if (minutes > 0) return `${minutes}m ${seconds % 60}s`
405
- return `${seconds}s`
406
- }
407
-
408
- private updateUI(progress: OperationProgress) {
409
- // Update your UI components
410
- document.querySelector('#progress-bar')?.setAttribute('value', progress.percentage.toString())
411
- document.querySelector('#progress-text')?.textContent =
412
- `${progress.message} (${progress.percentage}%)`
413
- }
414
- }
415
-
416
- // Use the tracker
417
- const tracker = new ProgressTracker()
418
- await operationClient.monitor('operation-id', {
419
- onProgress: tracker.onProgress,
420
- })
421
- ```
422
-
423
- ## React Integration
424
-
425
- ### useSSE Hook
426
-
427
- ```typescript
428
- import { useSSE } from '@robosystems/client/extensions/hooks'
429
-
430
- function OperationMonitor({ operationId }: { operationId: string }) {
431
- const {
432
- data,
433
- progress,
434
- status,
435
- error,
436
- isConnected
437
- } = useSSE(operationId, {
438
- onProgress: (p) => console.log('Progress:', p),
439
- onDataChunk: (chunk) => console.log('Chunk:', chunk),
440
- })
441
-
442
- if (error) return <div>Error: {error.message}</div>
443
- if (!isConnected) return <div>Connecting...</div>
444
-
445
- return (
446
- <div>
447
- <h3>Operation Status: {status}</h3>
448
- {progress && (
449
- <div>
450
- <progress value={progress.percentage} max="100" />
451
- <p>{progress.message}</p>
452
- </div>
453
- )}
454
- {data && (
455
- <div>
456
- <h4>Results:</h4>
457
- <pre>{JSON.stringify(data, null, 2)}</pre>
458
- </div>
459
- )}
460
- </div>
461
- )
462
- }
463
- ```
464
-
465
- ### useQueryWithSSE Hook
466
-
467
- ```typescript
468
- import { useQueryWithSSE } from '@robosystems/client/extensions/hooks'
469
-
470
- function QueryRunner() {
471
- const {
472
- execute,
473
- loading,
474
- data,
475
- error,
476
- progress,
477
- queuePosition
478
- } = useQueryWithSSE('your-graph-id')
479
-
480
- const runQuery = async () => {
481
- const result = await execute(
482
- 'MATCH (c:Company) RETURN c.name, c.revenue LIMIT 100'
483
- )
484
- console.log('Query completed:', result)
485
- }
486
-
487
- return (
488
- <div>
489
- <button onClick={runQuery} disabled={loading}>
490
- Run Query
491
- </button>
492
-
493
- {loading && (
494
- <div>
495
- {queuePosition > 0 && <p>Queue position: {queuePosition}</p>}
496
- {progress && <p>Progress: {progress.percentage}%</p>}
497
- </div>
498
- )}
499
-
500
- {error && <div className="error">{error.message}</div>}
501
-
502
- {data && (
503
- <table>
504
- <tbody>
505
- {data.rows.map((row, i) => (
506
- <tr key={i}>
507
- <td>{row['c.name']}</td>
508
- <td>${row['c.revenue'].toLocaleString()}</td>
509
- </tr>
510
- ))}
511
- </tbody>
512
- </table>
513
- )}
514
- </div>
515
- )
516
- }
517
- ```
518
-
519
- ### useCopy Hook for Data Import
520
-
521
- ```typescript
522
- import { useCopy } from '@robosystems/client/extensions/hooks'
523
-
524
- function DataImporter({ graphId }: { graphId: string }) {
525
- const {
526
- copyFromS3,
527
- loading,
528
- progress,
529
- error,
530
- result,
531
- queuePosition
532
- } = useCopy(graphId)
533
-
534
- const handleImport = async () => {
535
- const importResult = await copyFromS3({
536
- table_name: 'products',
537
- source_type: 's3',
538
- s3_path: 's3://data-bucket/products.csv',
539
- s3_access_key_id: process.env.NEXT_PUBLIC_AWS_KEY!,
540
- s3_secret_access_key: process.env.NEXT_PUBLIC_AWS_SECRET!,
541
- file_format: 'csv',
542
- })
543
-
544
- if (importResult?.status === 'completed') {
545
- alert(`Successfully imported ${importResult.rowsImported} products`)
546
- }
547
- }
548
-
549
- return (
550
- <div>
551
- <button onClick={handleImport} disabled={loading}>
552
- {loading ? 'Importing...' : 'Import Products'}
553
- </button>
554
-
555
- {progress && (
556
- <div>
557
- <p>{progress.message}</p>
558
- {progress.percent && (
559
- <progress value={progress.percent} max={100} />
560
- )}
561
- </div>
562
- )}
563
-
564
- {queuePosition && (
565
- <p>Queue position: {queuePosition}</p>
566
- )}
567
-
568
- {error && <p style={{ color: 'red' }}>Error: {error.message}</p>}
569
-
570
- {result && result.status === 'completed' && (
571
- <div style={{ color: 'green' }}>
572
- <p>Successfully imported {result.rowsImported} rows</p>
573
- <p>Execution time: {(result.executionTimeMs / 1000).toFixed(2)}s</p>
574
- </div>
575
- )}
576
- </div>
577
- )
578
- }
579
- ```
580
-
581
- ## Error Handling & Resilience
582
-
583
- ### Circuit Breaker Pattern
584
-
585
- The SSE system includes automatic circuit breaker protection:
586
-
587
- ```typescript
588
- // The circuit breaker automatically opens after 3 Redis failures
589
- // It will close again after a cooldown period
590
-
591
- sseClient.on('circuit_breaker_open', () => {
592
- console.log('SSE circuit breaker opened - falling back to polling')
593
- // Automatically degrades to polling
594
- })
595
-
596
- sseClient.on('circuit_breaker_closed', () => {
597
- console.log('SSE circuit breaker closed - resuming streaming')
598
- // Automatically resumes SSE when healthy
599
- })
600
- ```
601
-
602
- ### Graceful Degradation
603
-
604
- ```typescript
605
- import { QueryClient, FallbackStrategy } from '@robosystems/client/extensions'
606
-
607
- const queryClient = new QueryClient({
608
- baseUrl: 'https://api.robosystems.ai',
609
- fallbackStrategy: FallbackStrategy.AUTO, // Automatically choose best strategy
610
- })
611
-
612
- // Automatically uses best available method:
613
- // 1. SSE streaming (preferred)
614
- // 2. NDJSON streaming (if SSE unavailable)
615
- // 3. Polling (if streaming unavailable)
616
- // 4. Direct response (for small queries)
617
-
618
- const result = await queryClient.execute('graph-id', 'MATCH (n) RETURN n', {
619
- preferStreaming: true, // Hint to prefer streaming
620
- onFallback: (from, to) => {
621
- console.log(`Falling back from ${from} to ${to}`)
622
- },
623
- })
624
- ```
625
-
626
- ### Connection Pool Management
627
-
628
- ```typescript
629
- // SDK automatically manages SSE connection pooling
630
- const config = {
631
- maxConnections: 5, // Per-user limit enforced by server
632
- connectionTimeout: 10000, // 10 second timeout
633
- poolStrategy: 'FIFO', // First-in-first-out recycling
634
- }
635
-
636
- // Connections are automatically recycled when limits are reached
637
- const operations = [
638
- 'operation-1',
639
- 'operation-2',
640
- 'operation-3',
641
- 'operation-4',
642
- 'operation-5',
643
- 'operation-6', // Will recycle oldest connection
644
- ]
645
-
646
- // Monitor connection pool status
647
- sseClient.on('connection_recycled', ({ old, new }) => {
648
- console.log(`Recycled connection from ${old} to ${new}`)
649
- })
650
- ```
651
-
652
- ## Configuration
653
-
654
- ### Environment Variables
655
-
656
- ```bash
657
- # API Configuration
658
- NEXT_PUBLIC_ROBOSYSTEMS_API_URL=https://api.robosystems.ai
659
- ROBOSYSTEMS_API_KEY=your-api-key
660
-
661
- # SSE Configuration
662
- NEXT_PUBLIC_SSE_MAX_RETRIES=5
663
- NEXT_PUBLIC_SSE_RETRY_DELAY=1000
664
- NEXT_PUBLIC_SSE_HEARTBEAT_INTERVAL=30000
665
-
666
- # Feature Flags
667
- NEXT_PUBLIC_ENABLE_SSE=true
668
- NEXT_PUBLIC_PREFER_STREAMING=true
669
- ```
670
-
671
- ### Custom Configuration
672
-
673
- ```typescript
674
- import { RoboSystemsExtensions } from '@robosystems/client/extensions'
675
-
676
- const extensions = new RoboSystemsExtensions({
677
- // API Configuration
678
- baseUrl: process.env.NEXT_PUBLIC_ROBOSYSTEMS_API_URL,
679
-
680
- // Authentication
681
- credentials: 'include', // For cookies
682
- token: 'your-jwt-token', // Or use JWT token
683
- headers: {
684
- 'X-API-Key': process.env.ROBOSYSTEMS_API_KEY,
685
- },
686
-
687
- // Connection Settings
688
- maxRetries: 5,
689
- retryDelay: 1000,
690
-
691
- // S3 Configuration (for local development with LocalStack)
692
- s3EndpointUrl: process.env.S3_ENDPOINT_URL, // e.g., 'http://localhost:4566'
693
- })
694
- ```
695
-
696
- #### Local Development with LocalStack
697
-
698
- For local development using LocalStack, configure the S3 endpoint URL:
699
-
700
- ```typescript
701
- import { RoboSystemsExtensions } from '@robosystems/client/extensions'
702
-
703
- const extensions = new RoboSystemsExtensions({
704
- baseUrl: 'http://localhost:8000',
705
- credentials: 'include',
706
- // Override S3 endpoint for LocalStack
707
- s3EndpointUrl: 'http://localhost:4566',
708
- })
709
-
710
- // File uploads will now use LocalStack instead of AWS S3
711
- const result = await extensions.files.upload('graph-id', 'TableName', fileBuffer, {
712
- onProgress: (msg) => console.log(msg),
713
- })
714
- ```
715
-
716
- ## Performance Optimization
717
-
718
- ### Stream Processing for Large Datasets
719
-
720
- ```typescript
721
- import { StreamProcessor } from '@robosystems/client/extensions'
722
-
723
- const processor = new StreamProcessor({
724
- batchSize: 1000,
725
- concurrency: 3,
726
- })
727
-
728
- // Process large query results efficiently
729
- await processor.processStream('your-graph-id', 'MATCH (t:Transaction) RETURN t', {
730
- onBatch: async (batch) => {
731
- // Process batch of 1000 rows
732
- await saveToDB(batch)
733
- console.log(`Processed ${batch.length} transactions`)
734
- },
735
- onProgress: (processed, total) => {
736
- const percentage = (processed / total) * 100
737
- console.log(`Progress: ${percentage.toFixed(2)}%`)
738
- },
739
- })
740
- ```
741
-
742
- ### Caching with SSE Updates
743
-
744
- ```typescript
745
- import { CachedQueryClient } from '@robosystems/client/extensions'
746
-
747
- const cachedClient = new CachedQueryClient({
748
- ttl: 300000, // 5 minute cache
749
- maxSize: 100, // Cache up to 100 queries
750
- })
751
-
752
- // First call hits the API
753
- const result1 = await cachedClient.execute('graph-id', 'MATCH (n) RETURN COUNT(n)')
754
-
755
- // Second call returns from cache
756
- const result2 = await cachedClient.execute('graph-id', 'MATCH (n) RETURN COUNT(n)')
757
-
758
- // SSE updates automatically invalidate relevant cache entries
759
- cachedClient.on('cache_invalidated', (query) => {
760
- console.log('Cache invalidated for:', query)
761
- })
762
- ```
763
-
764
- ## Testing
765
-
766
- ### Mock SSE for Testing
767
-
768
- ```typescript
769
- import { MockSSEClient } from '@robosystems/client/extensions/testing'
770
-
771
- describe('SSE Integration', () => {
772
- it('should handle progress events', async () => {
773
- const mockClient = new MockSSEClient()
774
-
775
- // Set up mock events
776
- mockClient.simulateEvents([
777
- { event: EventType.OPERATION_STARTED, data: { message: 'Starting' } },
778
- { event: EventType.OPERATION_PROGRESS, data: { percentage: 50 } },
779
- { event: EventType.OPERATION_COMPLETED, data: { result: 'Success' } },
780
- ])
781
-
782
- // Test your component
783
- const { getByText } = render(
784
- <OperationMonitor
785
- operationId="test-123"
786
- sseClient={mockClient}
787
- />
788
- )
789
-
790
- await waitFor(() => {
791
- expect(getByText('Starting')).toBeInTheDocument()
792
- expect(getByText('50%')).toBeInTheDocument()
793
- expect(getByText('Success')).toBeInTheDocument()
794
- })
795
- })
796
- })
797
- ```
798
-
799
- ## API Reference
800
-
801
- ### Core Classes
802
-
803
- - **`SSEClient`** - Server-Sent Events client with auto-reconnection
804
- - **`QueryClient`** - Enhanced query execution with SSE support
805
- - **`TableIngestClient`** - Parquet file uploads to staging tables with progress monitoring
806
- - **`OperationClient`** - Long-running operation monitoring
807
- - **`StreamProcessor`** - Efficient stream processing for large datasets
808
-
809
- ### Event Types
810
-
811
- - **`EventType`** - Enum of all supported SSE event types
812
- - **`SSEEvent`** - Typed SSE event structure
813
- - **`OperationProgress`** - Progress update structure
814
- - **`OperationStatus`** - Operation status enum
815
-
816
- ### React Hooks
817
-
818
- - **`useSSE`** - Hook for SSE connection management
819
- - **`useQueryWithSSE`** - Hook for queries with progress
820
- - **`useCopy`** - Hook for data copy operations with progress
821
- - **`useOperation`** - Hook for operation monitoring
822
-
823
- ### Utilities
824
-
825
- - **`createSSEClient`** - Factory for configured SSE clients
826
- - **`formatDuration`** - Human-readable duration formatting
827
- - **`parseSSEEvent`** - SSE event parsing utility
828
-
829
- ## Troubleshooting
830
-
831
- ### Common Issues
832
-
833
- **Rate Limit Errors (429)**
834
-
835
- ```typescript
836
- // Handle rate limiting gracefully
837
- if (error.status === 429) {
838
- const retryAfter = error.headers['retry-after'] || 60
839
- console.log(`Rate limited. Retry after ${retryAfter} seconds`)
840
-
841
- // Use exponential backoff
842
- await sleep(retryAfter * 1000)
843
- await retry()
844
- }
845
- ```
846
-
847
- **Connection Drops**
848
-
849
- ```typescript
850
- // SSE automatically reconnects, but you can handle it manually
851
- sseClient.on('disconnected', () => {
852
- showNotification('Connection lost. Reconnecting...')
853
- })
854
-
855
- sseClient.on('connected', () => {
856
- showNotification('Connection restored')
857
- })
858
- ```
859
-
860
- **Circuit Breaker Open (503)**
861
-
862
- ```typescript
863
- // SSE system temporarily disabled
864
- if (error.status === 503) {
865
- console.log('SSE system unavailable - using fallback')
866
- // Automatically falls back to polling
867
- }
868
- ```
869
-
870
- ### Debug Mode
871
-
872
- ```typescript
873
- // Enable debug logging
874
- const sseClient = new SSEClient({
875
- baseUrl: 'https://api.robosystems.ai',
876
- debug: true, // Enables detailed logging
877
- })
878
-
879
- // Monitor all events
880
- sseClient.on('*', (event, data) => {
881
- console.log(`[SSE Debug] ${event}:`, data)
882
- })
883
- ```
884
-
885
- ## License
886
-
887
- MIT License - see [LICENSE](../../LICENSE) file for details.
888
-
889
- ## Contributing
890
-
891
- See the [Contributing Guide](../../CONTRIBUTING.md) for development setup and guidelines.
892
-
893
- ## Support
894
-
895
- - **API Reference**: [api.robosystems.ai/docs](https://api.robosystems.ai/docs)
896
- - **Discord**: [Join our community](https://discord.gg/V9vjcqstxX)
897
- - **Issues**: [GitHub Issues](https://github.com/RoboFinSystems/robosystems-typescript-client/issues)
898
-
899
- ---
900
-
901
- **RoboSystems Typescript Client Extensions** - Production-ready SSE streaming and real-time monitoring for financial knowledge graphs.