connectbase-client 3.1.0 → 3.2.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,35 @@
3
3
  본 SDK 의 모든 주요 변경사항을 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/) 형식으로 기록합니다.
4
4
  버전은 [Semantic Versioning](https://semver.org/lang/ko/) 을 따릅니다.
5
5
 
6
+ ## [3.2.0] - 2026-04-29
7
+
8
+ ### Added — Endpoint API 헬퍼 (`pollUntil` / `url`)
9
+
10
+ ComfyUI × 웹스토리지 같은 e2e 통합 패턴 (작업 제출 → 폴링 → 결과 저장) 을
11
+ 단일 진입점으로 묶기 위한 헬퍼 2개. `cb.endpoint.call()` 만으로도 가능했지만
12
+ 사용자가 매번 직접 작성하던 보일러플레이트를 SDK 가 흡수.
13
+
14
+ - **`cb.endpoint.pollUntil<T>(label, init, predicate, opts)`** — long-poll 한 줄
15
+ 처리. ComfyUI `/history/{id}`, A1111 `/sdapi/v1/progress`, 자체 큐 API 처럼
16
+ "작업 제출 → 폴링" 패턴 전용. `predicate` 가 값을 반환할 때까지 반복 호출,
17
+ HTTP 5xx/네트워크 오류는 재시도, 4xx 는 즉시 reject, `AbortSignal`/`timeoutMs`
18
+ 지원. `parse: "json" | "text" | "none"` 으로 본문 파싱 방식 선택.
19
+ - **`cb.endpoint.url(label, path)`** — 라벨 + path 의 최종 호출 URL 을 조립해서
20
+ 반환. WebSocket / `<img src>` / `new Image()` 같이 SDK 의 `call()` 이 아닌
21
+ 직접 호출이 필요할 때. `X-Public-Key` 는 자동 주입되지 않으므로 모델 서버가
22
+ 자체 토큰으로 인증을 별도 처리해야 함 (ConnectBase 는 dumb pipe).
23
+ - 신규 export: `PollUntilOptions` 타입.
24
+
25
+ ### Docs
26
+
27
+ - `examples/ai-image-generator/` — UMD CDN 한 줄 + 빌드 도구 0 으로 동작하는
28
+ ComfyUI × 웹스토리지 스타터. SDK 로딩 실패 감지, pre-flight 키 검증, 모든
29
+ KSampler seed 랜덤화, cache-bust 워크플로우 fetch, AbortController 일괄 취소,
30
+ step indicator, localStorage 갤러리, ⌘/Ctrl+Enter 단축키 등 11가지
31
+ 베스트프랙티스 채택.
32
+ - `docs/integration/comfyui-web-storage.md` — e2e 통합 가이드 + "왜 이 구조가
33
+ 정답인가" / "안티패턴 7가지".
34
+
6
35
  ## [3.1.0] - 2026-04-29
7
36
 
8
37
  ### Added — Endpoint API (로컬 모델 터널 dumb pipe)
package/README.md CHANGED
@@ -883,6 +883,71 @@ The SDK assembles the URL as `${baseUrl}/v1/proxy/${label}${path}` and forwards
883
883
  the request. Because the response is the raw `fetch` `Response`, streaming
884
884
  formats (SSE, chunked, NDJSON) work out of the box.
885
885
 
886
+ #### `cb.endpoint.pollUntil<T>(label, init, predicate, opts?): Promise<T>`
887
+
888
+ One-line "submit job → poll for result" pattern. Repeatedly calls the same
889
+ endpoint until `predicate` returns a value. Designed for ComfyUI `/history/{id}`,
890
+ A1111 `/sdapi/v1/progress`, or any custom queue API.
891
+
892
+ Behavior:
893
+ - Calls `cb.endpoint.call(label, init)` and passes the parsed body to `predicate`
894
+ - Returns `undefined` from `predicate` → wait `intervalMs` and retry
895
+ - Returns a value from `predicate` → resolve immediately with that value
896
+ - HTTP `5xx` / network error → retry. HTTP `4xx` → reject (job-level error)
897
+ - `timeoutMs` exceeded or `signal` aborted → reject
898
+
899
+ ```typescript
900
+ type Hist = Record<
901
+ string,
902
+ { outputs: Record<string, { images?: { filename: string }[] }> }
903
+ >
904
+
905
+ const filename = await cb.endpoint.pollUntil<string>(
906
+ 'comfyui-main',
907
+ { path: `/history/${promptId}` },
908
+ (data: Hist) => {
909
+ const entry = data[promptId]
910
+ if (!entry) return undefined // still queued
911
+ for (const out of Object.values(entry.outputs)) {
912
+ const img = out.images?.[0]
913
+ if (img) return img.filename
914
+ }
915
+ return undefined
916
+ },
917
+ { intervalMs: 1000, timeoutMs: 5 * 60_000 },
918
+ )
919
+ ```
920
+
921
+ **`PollUntilOptions`**
922
+
923
+ | Field | Type | Default | Description |
924
+ |-------|------|---------|-------------|
925
+ | `intervalMs` | `number` | `1500` | Poll interval in ms |
926
+ | `timeoutMs` | `number` | `300000` (5 min) | Total timeout in ms — reject if exceeded |
927
+ | `parse` | `'json' \| 'text' \| 'none'` | `'json'` | Body parser. `'json'` falls back to `undefined` on parse error |
928
+ | `signal` | `AbortSignal` | — | External cancel signal — reject immediately on abort |
929
+
930
+ #### `cb.endpoint.url(label, path): string`
931
+
932
+ Returns the assembled call URL (`${baseUrl}/v1/proxy/${label}${path}`) for cases
933
+ where the SDK's `call()` doesn't fit — `<img src>`, `new Image()`, native
934
+ `WebSocket`, etc.
935
+
936
+ ⚠️ Direct calls do **not** get automatic `X-Public-Key` injection. If your model
937
+ server requires authentication, your model server must validate a token of its
938
+ own (ConnectBase is a dumb pipe, not an auth gate).
939
+
940
+ ```typescript
941
+ // Render a ComfyUI output image directly into <img>
942
+ img.src =
943
+ cb.endpoint.url('comfyui-main', `/view?filename=${encodeURIComponent(name)}`)
944
+ ```
945
+
946
+ ```typescript
947
+ // Native WebSocket to a tunneled service
948
+ const ws = new WebSocket(cb.endpoint.url('my-ws-server', '/socket'))
949
+ ```
950
+
886
951
  ### Push Notifications
887
952
 
888
953
  ```typescript