@simplysm/service-client 13.0.85 → 13.0.88
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/README.md +274 -34
- package/package.json +4 -4
- package/docs/features.md +0 -190
- package/docs/protocol.md +0 -69
- package/docs/service-client.md +0 -176
- package/docs/transport.md +0 -88
- package/docs/types.md +0 -61
package/README.md
CHANGED
|
@@ -1,68 +1,308 @@
|
|
|
1
1
|
# @simplysm/service-client
|
|
2
2
|
|
|
3
|
-
WebSocket
|
|
3
|
+
WebSocket 기반 RPC 서비스 클라이언트. 자동 재연결, 이벤트 구독, 파일 업로드/다운로드, ORM 연동을 지원한다.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 설치
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install @simplysm/service-client
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
**의존성:** `@simplysm/core-common`, `@simplysm/orm-common`, `@simplysm/service-common`
|
|
12
|
+
|
|
13
|
+
## 주요 사용법
|
|
14
|
+
|
|
15
|
+
### 클라이언트 생성 및 연결
|
|
12
16
|
|
|
13
17
|
```typescript
|
|
14
18
|
import { createServiceClient } from "@simplysm/service-client";
|
|
15
19
|
|
|
16
|
-
// Create and connect
|
|
17
20
|
const client = createServiceClient("my-app", {
|
|
18
21
|
host: "localhost",
|
|
19
22
|
port: 3000,
|
|
23
|
+
ssl: false,
|
|
24
|
+
maxReconnectCount: 10, // 0이면 재연결 비활성화
|
|
20
25
|
});
|
|
26
|
+
|
|
21
27
|
await client.connect();
|
|
28
|
+
// ... 사용 ...
|
|
29
|
+
await client.close();
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`ServiceClient` 클래스를 직접 사용할 수도 있다.
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { ServiceClient } from "@simplysm/service-client";
|
|
36
|
+
|
|
37
|
+
const client = new ServiceClient("my-app", {
|
|
38
|
+
host: "localhost",
|
|
39
|
+
port: 3000,
|
|
40
|
+
});
|
|
41
|
+
```
|
|
22
42
|
|
|
23
|
-
|
|
24
|
-
await client.auth(token);
|
|
43
|
+
### 서비스 호출 (RPC)
|
|
25
44
|
|
|
26
|
-
|
|
45
|
+
```typescript
|
|
46
|
+
// 타입 안전한 서비스 프록시
|
|
27
47
|
const userService = client.getService<UserService>("User");
|
|
28
|
-
const users = await userService.
|
|
48
|
+
const users = await userService.findAll();
|
|
49
|
+
const user = await userService.findById(1);
|
|
29
50
|
|
|
30
|
-
//
|
|
31
|
-
const
|
|
51
|
+
// 직접 호출
|
|
52
|
+
const result = await client.send("User", "findById", [1]);
|
|
32
53
|
|
|
33
|
-
//
|
|
34
|
-
const
|
|
35
|
-
console.log(
|
|
54
|
+
// 진행률 콜백과 함께 호출
|
|
55
|
+
const result = await client.send("User", "exportData", [], {
|
|
56
|
+
request: (state) => console.log(`요청 전송: ${state.completedSize}/${state.totalSize}`),
|
|
57
|
+
response: (state) => console.log(`응답 수신: ${state.completedSize}/${state.totalSize}`),
|
|
36
58
|
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 인증
|
|
37
62
|
|
|
38
|
-
|
|
63
|
+
```typescript
|
|
64
|
+
await client.auth(jwtToken);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
재연결 시 인증 토큰이 자동으로 재전송된다.
|
|
68
|
+
|
|
69
|
+
### 이벤트 구독
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { defineEvent } from "@simplysm/service-common";
|
|
73
|
+
|
|
74
|
+
const OrderCreated = defineEvent<{ shopId: string }, { orderId: string; amount: number }>(
|
|
75
|
+
"order-created"
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
// 이벤트 구독 (info로 필터 조건 전달)
|
|
79
|
+
const key = await client.addListener(
|
|
80
|
+
OrderCreated,
|
|
81
|
+
{ shopId: "shop-1" },
|
|
82
|
+
async (data) => {
|
|
83
|
+
// data: { orderId: string; amount: number }
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
// 이벤트 구독 해제
|
|
39
88
|
await client.removeListener(key);
|
|
40
|
-
|
|
89
|
+
|
|
90
|
+
// 이벤트 발행 (서버를 통해 다른 클라이언트에 전달)
|
|
91
|
+
await client.emitEvent(
|
|
92
|
+
OrderCreated,
|
|
93
|
+
(info) => info.shopId === "shop-1",
|
|
94
|
+
{ orderId: "order-123", amount: 50000 }
|
|
95
|
+
);
|
|
41
96
|
```
|
|
42
97
|
|
|
43
|
-
|
|
98
|
+
재연결 시 이벤트 리스너가 서버에 자동으로 재등록된다.
|
|
44
99
|
|
|
45
|
-
|
|
46
|
-
|----------|------|-------------|
|
|
47
|
-
| Service Client | [docs/service-client.md](docs/service-client.md) | Main `ServiceClient` class and factory function |
|
|
48
|
-
| Types | [docs/types.md](docs/types.md) | Connection options, progress types |
|
|
49
|
-
| Transport | [docs/transport.md](docs/transport.md) | Socket provider and service transport layer |
|
|
50
|
-
| Protocol | [docs/protocol.md](docs/protocol.md) | Client protocol wrapper with Web Worker offloading |
|
|
51
|
-
| Features | [docs/features.md](docs/features.md) | Event client, file client, ORM connector |
|
|
100
|
+
### 파일 업로드/다운로드
|
|
52
101
|
|
|
53
|
-
|
|
102
|
+
파일 업로드는 `auth()`로 인증한 후에만 사용할 수 있다.
|
|
54
103
|
|
|
104
|
+
```typescript
|
|
105
|
+
// 업로드 (인증 필수)
|
|
106
|
+
await client.auth(jwtToken);
|
|
107
|
+
const results = await client.uploadFile(fileInput.files);
|
|
108
|
+
// results: ServiceUploadResult[] (path, filename, size)
|
|
109
|
+
|
|
110
|
+
// { name, data } 객체 배열도 지원
|
|
111
|
+
await client.uploadFile([
|
|
112
|
+
{ name: "report.xlsx", data: uint8ArrayData },
|
|
113
|
+
]);
|
|
114
|
+
|
|
115
|
+
// 다운로드 (Uint8Array 반환)
|
|
116
|
+
const buffer = await client.downloadFileBuffer("uploads/report.xlsx");
|
|
55
117
|
```
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
118
|
+
|
|
119
|
+
### 진행률 추적
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
// 이벤트 기반 (모든 요청/응답에 대해)
|
|
123
|
+
client.on("request-progress", ({ uuid, totalSize, completedSize }) => {
|
|
124
|
+
// 요청 전송 진행률
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
client.on("response-progress", ({ uuid, totalSize, completedSize }) => {
|
|
128
|
+
// 응답 수신 진행률
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// 연결 상태 변경
|
|
132
|
+
client.on("state", (state) => {
|
|
133
|
+
// "connected" | "closed" | "reconnecting"
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// 서버 HMR 리로드 알림
|
|
137
|
+
client.on("reload", (changedFiles) => {
|
|
138
|
+
// changedFiles: Set<string>
|
|
139
|
+
location.reload();
|
|
140
|
+
});
|
|
62
141
|
```
|
|
63
142
|
|
|
64
|
-
|
|
143
|
+
### ORM 클라이언트 연동
|
|
144
|
+
|
|
145
|
+
서버의 ORM 서비스를 통해 클라이언트에서 DbContext를 사용한다.
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import { createOrmClientConnector } from "@simplysm/service-client";
|
|
149
|
+
|
|
150
|
+
const ormConnector = createOrmClientConnector(client);
|
|
151
|
+
|
|
152
|
+
// 트랜잭션 포함 연결
|
|
153
|
+
const result = await ormConnector.connect(
|
|
154
|
+
{
|
|
155
|
+
dbContextDef: MyDb,
|
|
156
|
+
connOpt: { configName: "main" },
|
|
157
|
+
// 선택적: DB/스키마 오버라이드
|
|
158
|
+
// dbContextOpt: { database: "mydb", schema: "dbo" },
|
|
159
|
+
},
|
|
160
|
+
async (db) => {
|
|
161
|
+
return await db.user().execute();
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
// 트랜잭션 없이 연결
|
|
166
|
+
const result = await ormConnector.connectWithoutTransaction(
|
|
167
|
+
{ dbContextDef: MyDb, connOpt: { configName: "main" } },
|
|
168
|
+
async (db) => {
|
|
169
|
+
return await db.user().execute();
|
|
170
|
+
}
|
|
171
|
+
);
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## API 레퍼런스
|
|
175
|
+
|
|
176
|
+
### `createServiceClient(name, options)`
|
|
177
|
+
|
|
178
|
+
`ServiceClient` 인스턴스를 생성하는 팩토리 함수.
|
|
179
|
+
|
|
180
|
+
| 파라미터 | 타입 | 설명 |
|
|
181
|
+
|---------|------|------|
|
|
182
|
+
| `name` | `string` | 클라이언트 식별 이름 |
|
|
183
|
+
| `options` | `ServiceConnectionOptions` | 연결 설정 |
|
|
184
|
+
|
|
185
|
+
### `ServiceClient`
|
|
186
|
+
|
|
187
|
+
`EventEmitter<ServiceClientEvents>`를 확장한 메인 클라이언트 클래스.
|
|
188
|
+
|
|
189
|
+
**속성:**
|
|
190
|
+
|
|
191
|
+
| 이름 | 타입 | 설명 |
|
|
192
|
+
|------|------|------|
|
|
193
|
+
| `name` | `string` | 클라이언트 이름 (읽기 전용) |
|
|
194
|
+
| `options` | `ServiceConnectionOptions` | 연결 설정 (읽기 전용) |
|
|
195
|
+
| `connected` | `boolean` | 현재 연결 상태 |
|
|
196
|
+
| `hostUrl` | `string` | `http(s)://host:port` 형식 URL |
|
|
197
|
+
|
|
198
|
+
**메서드:**
|
|
199
|
+
|
|
200
|
+
| 메서드 | 반환 | 설명 |
|
|
201
|
+
|--------|------|------|
|
|
202
|
+
| `connect()` | `Promise<void>` | 서버에 연결 |
|
|
203
|
+
| `close()` | `Promise<void>` | 연결 종료 |
|
|
204
|
+
| `auth(token)` | `Promise<void>` | JWT 토큰으로 인증 |
|
|
205
|
+
| `send(serviceName, methodName, params, progress?)` | `Promise<unknown>` | RPC 호출 |
|
|
206
|
+
| `getService<T>(serviceName)` | `ServiceProxy<T>` | 타입 안전 서비스 프록시 생성 |
|
|
207
|
+
| `addListener(eventDef, info, cb)` | `Promise<string>` | 이벤트 구독 (키 반환) |
|
|
208
|
+
| `removeListener(key)` | `Promise<void>` | 이벤트 구독 해제 |
|
|
209
|
+
| `emitEvent(eventDef, infoSelector, data)` | `Promise<void>` | 이벤트 발행 |
|
|
210
|
+
| `uploadFile(files)` | `Promise<ServiceUploadResult[]>` | 파일 업로드 (인증 필수) |
|
|
211
|
+
| `downloadFileBuffer(relPath)` | `Promise<Bytes>` | 파일 다운로드 |
|
|
212
|
+
|
|
213
|
+
**이벤트:**
|
|
214
|
+
|
|
215
|
+
| 이벤트 | 데이터 타입 | 설명 |
|
|
216
|
+
|--------|-----------|------|
|
|
217
|
+
| `request-progress` | `ServiceProgressState` | 요청 전송 진행률 |
|
|
218
|
+
| `response-progress` | `ServiceProgressState` | 응답 수신 진행률 |
|
|
219
|
+
| `state` | `"connected" \| "closed" \| "reconnecting"` | 연결 상태 변경 |
|
|
220
|
+
| `reload` | `Set<string>` | 서버 HMR 리로드 알림 |
|
|
221
|
+
|
|
222
|
+
### `ServiceProxy<TService>`
|
|
223
|
+
|
|
224
|
+
서비스의 모든 메서드 반환 타입을 `Promise`로 감싸는 유틸리티 타입.
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
type ServiceProxy<TService> = {
|
|
228
|
+
[K in keyof TService]: TService[K] extends (...args: infer P) => infer R
|
|
229
|
+
? (...args: P) => Promise<Awaited<R>>
|
|
230
|
+
: never;
|
|
231
|
+
};
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### `ServiceConnectionOptions`
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
interface ServiceConnectionOptions {
|
|
238
|
+
port: number;
|
|
239
|
+
host: string;
|
|
240
|
+
ssl?: boolean; // HTTPS/WSS 사용 (기본: false)
|
|
241
|
+
maxReconnectCount?: number; // 최대 재연결 시도 (기본: 10, 0=비활성화)
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### `ServiceProgress` / `ServiceProgressState`
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
interface ServiceProgress {
|
|
249
|
+
request?: (s: ServiceProgressState) => void;
|
|
250
|
+
response?: (s: ServiceProgressState) => void;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
interface ServiceProgressState {
|
|
254
|
+
uuid: string;
|
|
255
|
+
totalSize: number;
|
|
256
|
+
completedSize: number;
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### `createOrmClientConnector(serviceClient)`
|
|
261
|
+
|
|
262
|
+
`OrmClientConnector` 인스턴스를 생성한다.
|
|
263
|
+
|
|
264
|
+
**`OrmClientConnector` 메서드:**
|
|
265
|
+
|
|
266
|
+
| 메서드 | 설명 |
|
|
267
|
+
|--------|------|
|
|
268
|
+
| `connect(config, callback)` | 트랜잭션 포함 DB 연결. 외래 키 제약 위반 시 친화적 에러 메시지 제공 |
|
|
269
|
+
| `connectWithoutTransaction(config, callback)` | 트랜잭션 없이 DB 연결 |
|
|
270
|
+
|
|
271
|
+
### `OrmConnectOptions<TDef>`
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
interface OrmConnectOptions<TDef extends DbContextDef<any, any, any>> {
|
|
275
|
+
dbContextDef: TDef;
|
|
276
|
+
connOpt: DbConnOptions & { configName: string };
|
|
277
|
+
dbContextOpt?: {
|
|
278
|
+
database: string;
|
|
279
|
+
schema: string;
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### 하위 모듈
|
|
285
|
+
|
|
286
|
+
다음 인터페이스와 팩토리 함수도 export되며, 커스텀 구성이 필요할 때 사용한다.
|
|
287
|
+
|
|
288
|
+
| Export | 설명 |
|
|
289
|
+
|--------|------|
|
|
290
|
+
| `createSocketProvider(url, clientName, maxReconnectCount)` | WebSocket 연결 관리 (하트비트, 재연결) |
|
|
291
|
+
| `SocketProvider` | 소켓 프로바이더 인터페이스 |
|
|
292
|
+
| `createServiceTransport(socket, protocol)` | 요청/응답 매칭 및 메시지 라우팅 |
|
|
293
|
+
| `ServiceTransport` | 트랜스포트 인터페이스 |
|
|
294
|
+
| `createClientProtocolWrapper(protocol)` | Worker 기반 인코딩/디코딩 래퍼 |
|
|
295
|
+
| `ClientProtocolWrapper` | 프로토콜 래퍼 인터페이스 |
|
|
296
|
+
| `createEventClient(transport)` | 이벤트 구독/발행 관리 |
|
|
297
|
+
| `EventClient` | 이벤트 클라이언트 인터페이스 |
|
|
298
|
+
| `createFileClient(hostUrl, clientName)` | HTTP 기반 파일 업로드/다운로드 |
|
|
299
|
+
| `FileClient` | 파일 클라이언트 인터페이스 |
|
|
300
|
+
| `OrmClientDbContextExecutor` | `DbContextExecutor` 구현체 (RPC 경유) |
|
|
301
|
+
|
|
302
|
+
## 내부 동작
|
|
65
303
|
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
304
|
+
- **하트비트:** 5초 간격 ping 전송, 30초 타임아웃 시 연결 끊김 감지 후 자동 재연결
|
|
305
|
+
- **재연결:** 3초 간격 재시도, 재연결 성공 시 인증 토큰 재전송 및 이벤트 자동 재구독
|
|
306
|
+
- **대용량 메시지:** Web Worker에서 인코딩/디코딩 (30KB 이상 또는 Uint8Array 포함 시)
|
|
307
|
+
- **프로토콜:** 3MB 초과 시 300KB 청크 자동 분할, 진행률 이벤트 발생
|
|
308
|
+
- **소켓 종료 시:** 모든 대기 중인 요청이 자동으로 reject되어 메모리 누수 방지
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/service-client",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.88",
|
|
4
4
|
"description": "Simplysm package - Service module (client)",
|
|
5
5
|
"author": "simplysm",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"sideEffects": false,
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"consola": "^3.4.2",
|
|
23
|
-
"@simplysm/core-common": "13.0.
|
|
24
|
-
"@simplysm/
|
|
25
|
-
"@simplysm/
|
|
23
|
+
"@simplysm/core-common": "13.0.88",
|
|
24
|
+
"@simplysm/orm-common": "13.0.88",
|
|
25
|
+
"@simplysm/service-common": "13.0.88"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/ws": "^8.18.1",
|
package/docs/features.md
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
# Features
|
|
2
|
-
|
|
3
|
-
Higher-level feature modules for events, file operations, and ORM database access.
|
|
4
|
-
|
|
5
|
-
## Event Client
|
|
6
|
-
|
|
7
|
-
### `EventClient`
|
|
8
|
-
|
|
9
|
-
**Interface** -- manages server-sent event subscriptions with automatic recovery on reconnect.
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
interface EventClient {
|
|
13
|
-
addListener<TInfo, TData>(
|
|
14
|
-
eventDef: ServiceEventDef<TInfo, TData>,
|
|
15
|
-
info: TInfo,
|
|
16
|
-
cb: (data: TData) => PromiseLike<void>,
|
|
17
|
-
): Promise<string>;
|
|
18
|
-
removeListener(key: string): Promise<void>;
|
|
19
|
-
emit<TInfo, TData>(
|
|
20
|
-
eventDef: ServiceEventDef<TInfo, TData>,
|
|
21
|
-
infoSelector: (item: TInfo) => boolean,
|
|
22
|
-
data: TData,
|
|
23
|
-
): Promise<void>;
|
|
24
|
-
resubscribeAll(): Promise<void>;
|
|
25
|
-
}
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### Methods
|
|
29
|
-
|
|
30
|
-
#### `addListener(eventDef, info, cb)`
|
|
31
|
-
|
|
32
|
-
Registers an event listener on the server and stores it locally for reconnect recovery.
|
|
33
|
-
|
|
34
|
-
| Parameter | Type | Description |
|
|
35
|
-
|-----------|------|-------------|
|
|
36
|
-
| `eventDef` | `ServiceEventDef<TInfo, TData>` | Event definition (from `@simplysm/service-common`) |
|
|
37
|
-
| `info` | `TInfo` | Metadata attached to this listener (used for filtering) |
|
|
38
|
-
| `cb` | `(data: TData) => PromiseLike<void>` | Callback invoked when the event fires |
|
|
39
|
-
|
|
40
|
-
**Returns:** A unique key string for removing this listener later.
|
|
41
|
-
|
|
42
|
-
#### `removeListener(key)`
|
|
43
|
-
|
|
44
|
-
Removes a listener locally and notifies the server. Safe to call even when disconnected (the server auto-cleans on disconnect).
|
|
45
|
-
|
|
46
|
-
#### `emit(eventDef, infoSelector, data)`
|
|
47
|
-
|
|
48
|
-
Emits an event to other connected clients. Queries the server for registered listeners matching `eventDef`, filters them with `infoSelector`, and sends data to the matching subset.
|
|
49
|
-
|
|
50
|
-
#### `resubscribeAll()`
|
|
51
|
-
|
|
52
|
-
Re-registers all locally stored listeners with the server. Called automatically by `ServiceClient` on reconnection.
|
|
53
|
-
|
|
54
|
-
### `createEventClient()`
|
|
55
|
-
|
|
56
|
-
```typescript
|
|
57
|
-
function createEventClient(transport: ServiceTransport): EventClient
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
## File Client
|
|
63
|
-
|
|
64
|
-
### `FileClient`
|
|
65
|
-
|
|
66
|
-
**Interface** -- HTTP-based file upload and download.
|
|
67
|
-
|
|
68
|
-
```typescript
|
|
69
|
-
interface FileClient {
|
|
70
|
-
download(relPath: string): Promise<Bytes>;
|
|
71
|
-
upload(
|
|
72
|
-
files: File[] | FileList | { name: string; data: BlobPart }[],
|
|
73
|
-
authToken: string,
|
|
74
|
-
): Promise<ServiceUploadResult[]>;
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### Methods
|
|
79
|
-
|
|
80
|
-
#### `download(relPath)`
|
|
81
|
-
|
|
82
|
-
Downloads a file from the server via HTTP GET.
|
|
83
|
-
|
|
84
|
-
| Parameter | Type | Description |
|
|
85
|
-
|-----------|------|-------------|
|
|
86
|
-
| `relPath` | `string` | Relative file path on the server |
|
|
87
|
-
|
|
88
|
-
**Returns:** `Uint8Array` containing the file contents.
|
|
89
|
-
|
|
90
|
-
#### `upload(files, authToken)`
|
|
91
|
-
|
|
92
|
-
Uploads one or more files via HTTP POST (`multipart/form-data`). Accepts browser `File` objects, a `FileList`, or plain objects with `name` and `data` properties.
|
|
93
|
-
|
|
94
|
-
| Parameter | Type | Description |
|
|
95
|
-
|-----------|------|-------------|
|
|
96
|
-
| `files` | `File[] \| FileList \| { name: string; data: BlobPart }[]` | Files to upload |
|
|
97
|
-
| `authToken` | `string` | Bearer token sent in the `Authorization` header |
|
|
98
|
-
|
|
99
|
-
**Returns:** `ServiceUploadResult[]` -- array of `{ path, filename, size }` for each uploaded file.
|
|
100
|
-
|
|
101
|
-
### `createFileClient()`
|
|
102
|
-
|
|
103
|
-
```typescript
|
|
104
|
-
function createFileClient(hostUrl: string, clientName: string): FileClient
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
## ORM Client
|
|
110
|
-
|
|
111
|
-
Utilities for accessing databases through the service server's ORM service.
|
|
112
|
-
|
|
113
|
-
### `OrmConnectOptions<TDef>`
|
|
114
|
-
|
|
115
|
-
**Interface** -- configuration for an ORM connection via the service client.
|
|
116
|
-
|
|
117
|
-
```typescript
|
|
118
|
-
interface OrmConnectOptions<TDef extends DbContextDef<any, any, any>> {
|
|
119
|
-
dbContextDef: TDef;
|
|
120
|
-
connOpt: DbConnOptions & { configName: string };
|
|
121
|
-
dbContextOpt?: {
|
|
122
|
-
database: string;
|
|
123
|
-
schema: string;
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
| Property | Type | Description |
|
|
129
|
-
|----------|------|-------------|
|
|
130
|
-
| `dbContextDef` | `TDef` | Database context definition (from `@simplysm/orm-common`) |
|
|
131
|
-
| `connOpt` | `DbConnOptions & { configName: string }` | Connection options including the named config |
|
|
132
|
-
| `dbContextOpt` | `{ database: string; schema: string }` | Optional database/schema overrides |
|
|
133
|
-
|
|
134
|
-
---
|
|
135
|
-
|
|
136
|
-
### `OrmClientConnector`
|
|
137
|
-
|
|
138
|
-
**Interface** -- high-level API for executing ORM operations through the service client.
|
|
139
|
-
|
|
140
|
-
```typescript
|
|
141
|
-
interface OrmClientConnector {
|
|
142
|
-
connect<TDef extends DbContextDef<any, any, any>, R>(
|
|
143
|
-
config: OrmConnectOptions<TDef>,
|
|
144
|
-
callback: (db: DbContextInstance<TDef>) => Promise<R> | R,
|
|
145
|
-
): Promise<R>;
|
|
146
|
-
connectWithoutTransaction<TDef extends DbContextDef<any, any, any>, R>(
|
|
147
|
-
config: OrmConnectOptions<TDef>,
|
|
148
|
-
callback: (db: DbContextInstance<TDef>) => Promise<R> | R,
|
|
149
|
-
): Promise<R>;
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
#### `connect(config, callback)`
|
|
154
|
-
|
|
155
|
-
Opens a transactional database connection, executes the callback, and automatically commits or rolls back.
|
|
156
|
-
|
|
157
|
-
Foreign key constraint violations are caught and re-thrown with a user-friendly message.
|
|
158
|
-
|
|
159
|
-
#### `connectWithoutTransaction(config, callback)`
|
|
160
|
-
|
|
161
|
-
Same as `connect()` but without transaction wrapping. Useful for read-only operations or when manual transaction control is needed.
|
|
162
|
-
|
|
163
|
-
### `createOrmClientConnector()`
|
|
164
|
-
|
|
165
|
-
```typescript
|
|
166
|
-
function createOrmClientConnector(serviceClient: ServiceClient): OrmClientConnector
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
---
|
|
170
|
-
|
|
171
|
-
### `OrmClientDbContextExecutor`
|
|
172
|
-
|
|
173
|
-
**Class** -- implements `DbContextExecutor` from `@simplysm/orm-common` by delegating all database operations to the server's `OrmService` via RPC.
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
class OrmClientDbContextExecutor implements DbContextExecutor {
|
|
177
|
-
constructor(client: ServiceClient, opt: DbConnOptions & { configName: string });
|
|
178
|
-
getInfo(): Promise<{ dialect: Dialect; database?: string; schema?: string }>;
|
|
179
|
-
connect(): Promise<void>;
|
|
180
|
-
beginTransaction(isolationLevel?: IsolationLevel): Promise<void>;
|
|
181
|
-
commitTransaction(): Promise<void>;
|
|
182
|
-
rollbackTransaction(): Promise<void>;
|
|
183
|
-
close(): Promise<void>;
|
|
184
|
-
executeDefs<T>(defs: QueryDef[], options?: (ResultMeta | undefined)[]): Promise<T[][]>;
|
|
185
|
-
executeParametrized(query: string, params?: unknown[]): Promise<unknown[][]>;
|
|
186
|
-
bulkInsert(tableName: string, columnDefs: Record<string, ColumnMeta>, records: Record<string, unknown>[]): Promise<void>;
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
All methods require an active connection (obtained via `connect()`). Calling any method before connecting throws an error.
|
package/docs/protocol.md
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# Protocol
|
|
2
|
-
|
|
3
|
-
Client-side protocol wrapper that optionally offloads encoding/decoding to a Web Worker for large payloads.
|
|
4
|
-
|
|
5
|
-
## `ClientProtocolWrapper`
|
|
6
|
-
|
|
7
|
-
**Interface** -- encodes outgoing messages into binary chunks and decodes incoming binary data.
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
interface ClientProtocolWrapper {
|
|
11
|
-
encode(uuid: string, message: ServiceMessage): Promise<{ chunks: Bytes[]; totalSize: number }>;
|
|
12
|
-
decode(bytes: Bytes): Promise<ServiceMessageDecodeResult<ServiceMessage>>;
|
|
13
|
-
}
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
### Methods
|
|
17
|
-
|
|
18
|
-
#### `encode(uuid, message)`
|
|
19
|
-
|
|
20
|
-
Encodes a service message into one or more binary chunks for transmission.
|
|
21
|
-
|
|
22
|
-
| Parameter | Type | Description |
|
|
23
|
-
|-----------|------|-------------|
|
|
24
|
-
| `uuid` | `string` | Request identifier |
|
|
25
|
-
| `message` | `ServiceMessage` | The message to encode |
|
|
26
|
-
|
|
27
|
-
**Returns:** `{ chunks: Bytes[]; totalSize: number }`
|
|
28
|
-
|
|
29
|
-
#### `decode(bytes)`
|
|
30
|
-
|
|
31
|
-
Decodes a binary chunk received from the server.
|
|
32
|
-
|
|
33
|
-
| Parameter | Type | Description |
|
|
34
|
-
|-----------|------|-------------|
|
|
35
|
-
| `bytes` | `Bytes` | Raw binary data |
|
|
36
|
-
|
|
37
|
-
**Returns:** `ServiceMessageDecodeResult<ServiceMessage>`
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## `createClientProtocolWrapper()`
|
|
42
|
-
|
|
43
|
-
**Factory function** -- creates a `ClientProtocolWrapper` that delegates to a Web Worker for large payloads.
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
function createClientProtocolWrapper(
|
|
47
|
-
protocol: ServiceProtocol,
|
|
48
|
-
): ClientProtocolWrapper
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### Worker Offloading Strategy
|
|
52
|
-
|
|
53
|
-
The wrapper applies a **30 KB threshold** to decide whether to process on the main thread or offload to a dedicated Web Worker:
|
|
54
|
-
|
|
55
|
-
**Encode** (main thread when any of these are false):
|
|
56
|
-
- Message body is a `Uint8Array`
|
|
57
|
-
- Message body is a string longer than 30 KB
|
|
58
|
-
- Message body is an array with more than 100 elements, or contains `Uint8Array` items
|
|
59
|
-
|
|
60
|
-
**Decode** (main thread when):
|
|
61
|
-
- Payload size is 30 KB or less
|
|
62
|
-
|
|
63
|
-
When a Web Worker is unavailable (e.g., in environments without `Worker` support), all processing falls back to the main thread.
|
|
64
|
-
|
|
65
|
-
### Worker Lifecycle
|
|
66
|
-
|
|
67
|
-
- A single shared `Worker` instance is created lazily on first use (singleton pattern).
|
|
68
|
-
- Worker tasks are tracked with a `LazyGcMap` that auto-expires entries after 60 seconds, preventing memory leaks from orphaned requests.
|
|
69
|
-
- For decode operations, binary data is transferred via zero-copy (`Transferable`) to avoid cloning overhead.
|
package/docs/service-client.md
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
# Service Client
|
|
2
|
-
|
|
3
|
-
The main entry point for connecting to and communicating with a `@simplysm/service-server` instance.
|
|
4
|
-
|
|
5
|
-
## `ServiceClient`
|
|
6
|
-
|
|
7
|
-
**Class** -- extends `EventEmitter<ServiceClientEvents>`
|
|
8
|
-
|
|
9
|
-
The primary facade that orchestrates WebSocket connectivity, RPC calls, authentication, event subscriptions, and file operations.
|
|
10
|
-
|
|
11
|
-
### Constructor
|
|
12
|
-
|
|
13
|
-
```typescript
|
|
14
|
-
new ServiceClient(name: string, options: ServiceConnectionOptions)
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
| Parameter | Type | Description |
|
|
18
|
-
|-----------|------|-------------|
|
|
19
|
-
| `name` | `string` | Client identifier (sent to server on connection) |
|
|
20
|
-
| `options` | `ServiceConnectionOptions` | Connection configuration (see [Types](types.md)) |
|
|
21
|
-
|
|
22
|
-
### Properties
|
|
23
|
-
|
|
24
|
-
| Property | Type | Description |
|
|
25
|
-
|----------|------|-------------|
|
|
26
|
-
| `name` | `string` | Client name (readonly) |
|
|
27
|
-
| `options` | `ServiceConnectionOptions` | Connection options (readonly) |
|
|
28
|
-
| `connected` | `boolean` | Whether the WebSocket is currently open |
|
|
29
|
-
| `hostUrl` | `string` | Computed HTTP(S) base URL (e.g. `https://localhost:3000`) |
|
|
30
|
-
|
|
31
|
-
### Methods
|
|
32
|
-
|
|
33
|
-
#### `connect()`
|
|
34
|
-
|
|
35
|
-
Opens the WebSocket connection to the server.
|
|
36
|
-
|
|
37
|
-
```typescript
|
|
38
|
-
await client.connect();
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
#### `close()`
|
|
42
|
-
|
|
43
|
-
Gracefully closes the WebSocket connection.
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
await client.close();
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
#### `auth(token)`
|
|
50
|
-
|
|
51
|
-
Authenticates the connection with the server. The token is stored internally and automatically re-sent on reconnection.
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
await client.auth(token: string): Promise<void>
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
#### `getService<TService>(serviceName)`
|
|
58
|
-
|
|
59
|
-
Creates a type-safe proxy for calling remote service methods. Every property access on the returned proxy returns an async function that sends an RPC request to the server.
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
const proxy = client.getService<MyService>("MyService");
|
|
63
|
-
const result = await proxy.someMethod(arg1, arg2);
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
**Returns:** `ServiceProxy<TService>` -- all methods wrapped to return `Promise<Awaited<R>>`
|
|
67
|
-
|
|
68
|
-
#### `send(serviceName, methodName, params, progress?)`
|
|
69
|
-
|
|
70
|
-
Low-level method to send an RPC request. Prefer `getService()` for type safety.
|
|
71
|
-
|
|
72
|
-
```typescript
|
|
73
|
-
await client.send(
|
|
74
|
-
serviceName: string,
|
|
75
|
-
methodName: string,
|
|
76
|
-
params: unknown[],
|
|
77
|
-
progress?: ServiceProgress,
|
|
78
|
-
): Promise<unknown>
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
#### `addListener(eventDef, info, cb)`
|
|
82
|
-
|
|
83
|
-
Subscribes to a server-sent event. Automatically re-subscribes on reconnection.
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
const key = await client.addListener<TInfo, TData>(
|
|
87
|
-
eventDef: ServiceEventDef<TInfo, TData>,
|
|
88
|
-
info: TInfo,
|
|
89
|
-
cb: (data: TData) => PromiseLike<void>,
|
|
90
|
-
): Promise<string>
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
**Returns:** A unique listener key for later removal.
|
|
94
|
-
|
|
95
|
-
**Throws:** `Error` if not connected.
|
|
96
|
-
|
|
97
|
-
#### `removeListener(key)`
|
|
98
|
-
|
|
99
|
-
Unsubscribes from a previously registered event listener.
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
await client.removeListener(key: string): Promise<void>
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
#### `emitEvent(eventDef, infoSelector, data)`
|
|
106
|
-
|
|
107
|
-
Emits an event to other connected clients that match the selector.
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
110
|
-
await client.emitEvent<TInfo, TData>(
|
|
111
|
-
eventDef: ServiceEventDef<TInfo, TData>,
|
|
112
|
-
infoSelector: (item: TInfo) => boolean,
|
|
113
|
-
data: TData,
|
|
114
|
-
): Promise<void>
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
#### `uploadFile(files)`
|
|
118
|
-
|
|
119
|
-
Uploads files to the server via HTTP POST. Requires prior authentication via `auth()`.
|
|
120
|
-
|
|
121
|
-
```typescript
|
|
122
|
-
const results = await client.uploadFile(
|
|
123
|
-
files: File[] | FileList | { name: string; data: BlobPart }[],
|
|
124
|
-
): Promise<ServiceUploadResult[]>
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
**Throws:** `Error` if no auth token is set.
|
|
128
|
-
|
|
129
|
-
#### `downloadFileBuffer(relPath)`
|
|
130
|
-
|
|
131
|
-
Downloads a file from the server as a `Uint8Array`.
|
|
132
|
-
|
|
133
|
-
```typescript
|
|
134
|
-
const bytes = await client.downloadFileBuffer(relPath: string): Promise<Bytes>
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Events
|
|
138
|
-
|
|
139
|
-
| Event | Payload | Description |
|
|
140
|
-
|-------|---------|-------------|
|
|
141
|
-
| `state` | `"connected" \| "closed" \| "reconnecting"` | Connection state changes |
|
|
142
|
-
| `reload` | `Set<string>` | Server-triggered reload with changed file paths |
|
|
143
|
-
| `request-progress` | `ServiceProgressState` | Upload/request progress updates |
|
|
144
|
-
| `response-progress` | `ServiceProgressState` | Download/response progress updates |
|
|
145
|
-
|
|
146
|
-
### Reconnection Behavior
|
|
147
|
-
|
|
148
|
-
- On reconnect, `auth()` is automatically re-called if a token was previously set.
|
|
149
|
-
- All event listeners registered via `addListener()` are automatically re-subscribed.
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
## `createServiceClient()`
|
|
154
|
-
|
|
155
|
-
**Factory function** -- convenience wrapper for the constructor.
|
|
156
|
-
|
|
157
|
-
```typescript
|
|
158
|
-
function createServiceClient(
|
|
159
|
-
name: string,
|
|
160
|
-
options: ServiceConnectionOptions,
|
|
161
|
-
): ServiceClient
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
---
|
|
165
|
-
|
|
166
|
-
## `ServiceProxy<TService>`
|
|
167
|
-
|
|
168
|
-
**Type** -- transforms a service interface so that all methods return `Promise<Awaited<R>>`. Non-function properties are excluded.
|
|
169
|
-
|
|
170
|
-
```typescript
|
|
171
|
-
type ServiceProxy<TService> = {
|
|
172
|
-
[K in keyof TService]: TService[K] extends (...args: infer P) => infer R
|
|
173
|
-
? (...args: P) => Promise<Awaited<R>>
|
|
174
|
-
: never;
|
|
175
|
-
};
|
|
176
|
-
```
|
package/docs/transport.md
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
# Transport
|
|
2
|
-
|
|
3
|
-
Low-level transport layer that manages the WebSocket connection and request/response multiplexing. These are internal building blocks used by `ServiceClient`; most consumers will not interact with them directly.
|
|
4
|
-
|
|
5
|
-
## `SocketProvider`
|
|
6
|
-
|
|
7
|
-
**Interface** -- abstraction over a reconnecting WebSocket connection with heartbeat monitoring.
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
interface SocketProvider {
|
|
11
|
-
readonly clientName: string;
|
|
12
|
-
readonly connected: boolean;
|
|
13
|
-
on<K extends keyof SocketProviderEvents>(type: K, listener: (data: SocketProviderEvents[K]) => void): void;
|
|
14
|
-
off<K extends keyof SocketProviderEvents>(type: K, listener: (data: SocketProviderEvents[K]) => void): void;
|
|
15
|
-
connect(): Promise<void>;
|
|
16
|
-
close(): Promise<void>;
|
|
17
|
-
send(data: Bytes): Promise<void>;
|
|
18
|
-
}
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### Events (`SocketProviderEvents`)
|
|
22
|
-
|
|
23
|
-
| Event | Payload | Description |
|
|
24
|
-
|-------|---------|-------------|
|
|
25
|
-
| `message` | `Bytes` | Raw binary message received from server |
|
|
26
|
-
| `state` | `"connected" \| "closed" \| "reconnecting"` | Connection state change |
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
## `createSocketProvider()`
|
|
31
|
-
|
|
32
|
-
**Factory function** -- creates a `SocketProvider` implementation backed by the browser `WebSocket` API.
|
|
33
|
-
|
|
34
|
-
```typescript
|
|
35
|
-
function createSocketProvider(
|
|
36
|
-
url: string,
|
|
37
|
-
clientName: string,
|
|
38
|
-
maxReconnectCount: number,
|
|
39
|
-
): SocketProvider
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### Behavior
|
|
43
|
-
|
|
44
|
-
- **Heartbeat**: Sends a ping (`0x01`) every 5 seconds. If no message is received for 30 seconds, the connection is considered lost and reconnection begins.
|
|
45
|
-
- **Reconnection**: On unexpected disconnect, retries up to `maxReconnectCount` times with a 3-second delay between attempts. Emits `"reconnecting"` state on each attempt and `"connected"` on success.
|
|
46
|
-
- **Graceful close**: `close()` sets a manual-close flag to suppress reconnection and waits up to 30 seconds for the socket to fully close.
|
|
47
|
-
- **Binary mode**: WebSocket is configured with `binaryType: "arraybuffer"`.
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## `ServiceTransport`
|
|
52
|
-
|
|
53
|
-
**Interface** -- multiplexes named request/response pairs over a single `SocketProvider`.
|
|
54
|
-
|
|
55
|
-
```typescript
|
|
56
|
-
interface ServiceTransport {
|
|
57
|
-
on<K extends keyof ServiceTransportEvents>(type: K, listener: (data: ServiceTransportEvents[K]) => void): void;
|
|
58
|
-
off<K extends keyof ServiceTransportEvents>(type: K, listener: (data: ServiceTransportEvents[K]) => void): void;
|
|
59
|
-
send(message: ServiceClientMessage, progress?: ServiceProgress): Promise<unknown>;
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
### Events (`ServiceTransportEvents`)
|
|
64
|
-
|
|
65
|
-
| Event | Payload | Description |
|
|
66
|
-
|-------|---------|-------------|
|
|
67
|
-
| `reload` | `Set<string>` | Server-initiated reload notification with changed file paths |
|
|
68
|
-
| `event` | `{ keys: string[]; data: unknown }` | Server-pushed event data |
|
|
69
|
-
|
|
70
|
-
---
|
|
71
|
-
|
|
72
|
-
## `createServiceTransport()`
|
|
73
|
-
|
|
74
|
-
**Factory function** -- creates a `ServiceTransport` that encodes/decodes messages through a protocol wrapper.
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
function createServiceTransport(
|
|
78
|
-
socket: SocketProvider,
|
|
79
|
-
protocol: ClientProtocolWrapper,
|
|
80
|
-
): ServiceTransport
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### Behavior
|
|
84
|
-
|
|
85
|
-
- Each `send()` call assigns a unique UUID, registers a pending-response listener, and encodes the message into one or more binary chunks.
|
|
86
|
-
- Progress callbacks are invoked for multi-chunk transfers.
|
|
87
|
-
- When the socket disconnects, all pending requests are rejected with `"Request canceled: Socket connection lost"`.
|
|
88
|
-
- Incoming messages are decoded and dispatched based on their name: `response`, `error`, `progress`, `reload`, or `evt:on`.
|
package/docs/types.md
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
# Types
|
|
2
|
-
|
|
3
|
-
Shared type definitions used across the service-client package.
|
|
4
|
-
|
|
5
|
-
## `ServiceConnectionOptions`
|
|
6
|
-
|
|
7
|
-
**Interface** -- configuration for connecting to a service server.
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
interface ServiceConnectionOptions {
|
|
11
|
-
port: number;
|
|
12
|
-
host: string;
|
|
13
|
-
ssl?: boolean;
|
|
14
|
-
maxReconnectCount?: number;
|
|
15
|
-
}
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
| Property | Type | Default | Description |
|
|
19
|
-
|----------|------|---------|-------------|
|
|
20
|
-
| `port` | `number` | -- | Server port number |
|
|
21
|
-
| `host` | `string` | -- | Server hostname or IP |
|
|
22
|
-
| `ssl` | `boolean` | `undefined` | Use `wss://` and `https://` when `true` |
|
|
23
|
-
| `maxReconnectCount` | `number` | `10` | Maximum reconnection attempts. Set to `0` to disable reconnection (disconnects immediately). |
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## `ServiceProgress`
|
|
28
|
-
|
|
29
|
-
**Interface** -- callbacks for monitoring request/response transfer progress.
|
|
30
|
-
|
|
31
|
-
```typescript
|
|
32
|
-
interface ServiceProgress {
|
|
33
|
-
request?: (s: ServiceProgressState) => void;
|
|
34
|
-
response?: (s: ServiceProgressState) => void;
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
| Property | Type | Description |
|
|
39
|
-
|----------|------|-------------|
|
|
40
|
-
| `request` | `(s: ServiceProgressState) => void` | Called as request chunks are sent |
|
|
41
|
-
| `response` | `(s: ServiceProgressState) => void` | Called as response chunks are received |
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## `ServiceProgressState`
|
|
46
|
-
|
|
47
|
-
**Interface** -- progress snapshot for a single transfer operation.
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
interface ServiceProgressState {
|
|
51
|
-
uuid: string;
|
|
52
|
-
totalSize: number;
|
|
53
|
-
completedSize: number;
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
| Property | Type | Description |
|
|
58
|
-
|----------|------|-------------|
|
|
59
|
-
| `uuid` | `string` | Unique identifier for the request |
|
|
60
|
-
| `totalSize` | `number` | Total payload size in bytes |
|
|
61
|
-
| `completedSize` | `number` | Bytes transferred so far |
|