@rscc/common-react 0.2.0 → 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 (2) hide show
  1. package/README.md +28 -7
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -17,7 +17,7 @@ npm i @rscc/common-react
17
17
  | 훅 | 시그니처 | 설명 |
18
18
  |---|---|---|
19
19
  | `useDebounce` | `useDebounce<T>(value, delayMs = 200): T` | 마지막 안정 값만 통과 — 자동완성 API 호출 절감 |
20
- | `useSse` | `useSse(options?)` → `{ start, cancel, text, sources, conversationId, error, isStreaming }` | SSE 구독 상태 훅 — 언마운트 시 자동 중단 |
20
+ | `useSse` | `useSse(options?)` → `{ start, cancel, text, sources, conversationId, error, isStreaming, finishReason }` | SSE 구독 상태 훅 — 언마운트 시 자동 중단, `finishReason` 으로 종료 사유 구분, opt-in `reconnect` |
21
21
 
22
22
  ## 사용 예시
23
23
 
@@ -35,19 +35,40 @@ const debounced = useDebounce(keyword, 200);
35
35
  ```ts
36
36
  import { useSse } from "@rscc/common-react";
37
37
 
38
- const { start, cancel, text, sources, conversationId, error, isStreaming } = useSse();
38
+ const { start, cancel, text, sources, conversationId, error, isStreaming, finishReason } = useSse();
39
39
 
40
40
  await start("/api/v1/chat/stream", { method: "POST", headers, body });
41
41
  // text: delta 누적 텍스트, sources: RAG 근거, error: in-band 오류 메시지
42
42
  // cancel(): 중단 — 그때까지의 text 는 보존되고 error 는 남지 않는다
43
+ // finishReason: 직전 스트림의 종료 사유 — 스트리밍 중/시작 전엔 null
43
44
  ```
44
45
 
45
46
  - 구독 전 검증 실패(`!res.ok`)는 응답 봉투의 `message` 를 `error` 로 노출한다.
46
47
  - `start` 재호출 시 이전 스트림을 중단하고 상태를 초기화한다.
47
- - 한계: `[DONE]` 정상 종료와 끊긴 스트림을 구분하는 신호가 없다 — 둘 다 `isStreaming=false`, `error=null` 로 끝난다.
48
+ - 반환 Promise 는 스트림 종료 시 resolve 한다 — 오류는 `error` 상태로 노출되며 reject 하지 않는다.
48
49
 
49
- ## 문서 / 저장소
50
+ `finishReason` (`SseFinishReason`) 으로 정상 종료와 끊김을 구분한다:
50
51
 
51
- - 상세 문서: [js/README.md](https://github.com/Jeonghyeon-Ryu/r-common/blob/master/js/README.md)
52
- - SSE 프레임 계약: [contracts/sse-frames.md](https://github.com/Jeonghyeon-Ryu/r-common/blob/master/contracts/sse-frames.md)
53
- - 저장소: [Jeonghyeon-Ryu/r-common](https://github.com/Jeonghyeon-Ryu/r-common) · MIT
52
+ | 값 | 의미 |
53
+ |---|---|
54
+ | `'done'` | `[DONE]` 종료 마커 수신 (in-band error 프레임 뒤의 `[DONE]` 포함 — `error` 와 공존) |
55
+ | `'aborted'` | `cancel()` / 새 `start()` 로 대체 / 언마운트로 인한 중단 |
56
+ | `'interrupted'` | `[DONE]` 없이 끝난 비정상 종료 — 무언 EOF, 전송 오류, 구독 전 검증 실패(`!res.ok`) 포함 |
57
+
58
+ ### useSse — 자동 재연결 (opt-in, 기본 off)
59
+
60
+ ```ts
61
+ const sse = useSse({ reconnect: { retries: 3, minDelayMs: 1000, maxDelayMs: 15000 } });
62
+ // 기본값: retries 3 · minDelayMs 1000 · maxDelayMs 15000 · factor 2 · jitter true (SseReconnectOptions)
63
+ ```
64
+
65
+ - 재연결 트리거는 **"스트림 시작(`res.ok`) 후 `[DONE]` 없이 끊긴 경우"뿐** — `'done'`/`'aborted'`/
66
+ 구독 전 실패(`!res.ok`)/in-band error 프레임 종료는 서버 의도로 보고 재연결하지 않는다.
67
+ - 각 시도는 **전체 재요청**이며 직전 시도의 `text`/`sources`/`conversationId`/`error` 를 초기화한다
68
+ (중복 누적 방지). 이어받기(Last-Event-ID)는 지원하지 않는다.
69
+ - [주의] 비멱등 POST 스트림은 전체 재요청이 서버 측 중복 생성으로 이어질 수 있으므로 멱등성이 보장될 때만 켤 것.
70
+
71
+ ## 관련 패키지
72
+
73
+ - 코어(SSE 파서 `readSseStream`·apiClient 등): [@rscc/common-core](https://www.npmjs.com/package/@rscc/common-core)
74
+ - 라이선스: MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rscc/common-react",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "RSCC 공통 React 훅 — useDebounce, useSse (@rscc/common-core 의 SSE 파서 래핑).",
5
5
  "keywords": [
6
6
  "rscc",
@@ -54,7 +54,7 @@
54
54
  "prepublishOnly": "npm run build"
55
55
  },
56
56
  "dependencies": {
57
- "@rscc/common-core": "^0.2.0"
57
+ "@rscc/common-core": "^0.3.0"
58
58
  },
59
59
  "peerDependencies": {
60
60
  "react": ">=18"