|
1 | 1 | import { useRef, useState } from 'react'; |
2 | 2 |
|
3 | | -import { getStockHistory, watchSelectedStocks, watchStockPrices } from './client/sdk.gen'; |
| 3 | +import { |
| 4 | + getStockHistory, |
| 5 | + watchSelectedStocks, |
| 6 | + watchSingleStock, |
| 7 | + watchStockPrices, |
| 8 | +} from './client/sdk.gen'; |
4 | 9 | import type { StockUpdate } from './client/types.gen'; |
5 | 10 |
|
6 | 11 | function App() { |
@@ -72,6 +77,32 @@ function App() { |
72 | 77 | setStatus('disconnected'); |
73 | 78 | }; |
74 | 79 |
|
| 80 | + // SSE with path parameter, query parameter, and error response |
| 81 | + const onWatchSingle = async () => { |
| 82 | + const controller = new AbortController(); |
| 83 | + controllerRef.current = controller; |
| 84 | + setStatus('connected'); |
| 85 | + setUpdates([]); |
| 86 | + |
| 87 | + try { |
| 88 | + const { stream } = await watchSingleStock({ |
| 89 | + path: { symbol: 'AAPL' }, |
| 90 | + query: { interval: 2 }, |
| 91 | + signal: controller.signal, |
| 92 | + }); |
| 93 | + |
| 94 | + for await (const update of stream) { |
| 95 | + setUpdates((prev) => [...prev, update]); |
| 96 | + } |
| 97 | + } catch { |
| 98 | + if (!controller.signal.aborted) { |
| 99 | + setStatus('error'); |
| 100 | + return; |
| 101 | + } |
| 102 | + } |
| 103 | + setStatus('disconnected'); |
| 104 | + }; |
| 105 | + |
75 | 106 | // Cancel the stream using AbortController |
76 | 107 | const onDisconnect = () => { |
77 | 108 | controllerRef.current?.abort(); |
@@ -112,6 +143,9 @@ function App() { |
112 | 143 | <button disabled={status === 'connected'} onClick={onWatchSelected}> |
113 | 144 | Watch Selected (POST) |
114 | 145 | </button> |
| 146 | + <button disabled={status === 'connected'} onClick={onWatchSingle}> |
| 147 | + Watch AAPL (Path Param) |
| 148 | + </button> |
115 | 149 | <button disabled={status !== 'connected'} onClick={onDisconnect}> |
116 | 150 | Disconnect |
117 | 151 | </button> |
|
0 commit comments