@simplysm/service-client 13.0.69 → 13.0.71
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 +28 -620
- package/dist/features/event-client.d.ts.map +1 -1
- package/dist/features/event-client.js +6 -3
- package/dist/features/event-client.js.map +1 -1
- package/dist/features/orm/orm-client-connector.js +1 -1
- package/dist/features/orm/orm-client-connector.js.map +1 -1
- package/dist/features/orm/orm-client-db-context-executor.js +7 -7
- package/dist/features/orm/orm-client-db-context-executor.js.map +1 -1
- package/dist/protocol/client-protocol-wrapper.js +2 -2
- package/dist/service-client.js +6 -6
- package/dist/service-client.js.map +1 -1
- package/dist/transport/service-transport.d.ts.map +1 -1
- package/dist/transport/service-transport.js +3 -1
- package/dist/transport/service-transport.js.map +1 -1
- package/dist/transport/socket-provider.js +6 -6
- package/dist/transport/socket-provider.js.map +1 -1
- package/dist/types/connection-config.d.ts +1 -1
- package/dist/types/connection-config.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/features/event-client.ts +12 -8
- package/src/features/file-client.ts +3 -3
- package/src/features/orm/orm-client-connector.ts +1 -1
- package/src/features/orm/orm-client-db-context-executor.ts +7 -7
- package/src/protocol/client-protocol-wrapper.ts +16 -16
- package/src/service-client.ts +12 -12
- package/src/transport/service-transport.ts +18 -15
- package/src/transport/socket-provider.ts +35 -35
- package/src/types/connection-config.ts +1 -1
- package/src/workers/client-protocol.worker.ts +9 -9
package/README.md
CHANGED
|
@@ -1,640 +1,48 @@
|
|
|
1
1
|
# @simplysm/service-client
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Works in both browser and Node.js environments, with built-in features like automatic message chunking/merging for large payloads, heartbeat-based connection monitoring, and automatic reconnection.
|
|
3
|
+
Simplysm package - Service module (client)
|
|
6
4
|
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
9
|
-
```bash
|
|
10
|
-
npm install @simplysm/service-client
|
|
11
|
-
# or
|
|
12
7
|
pnpm add @simplysm/service-client
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Main Modules
|
|
16
|
-
|
|
17
|
-
### Core Functions and Classes
|
|
18
|
-
|
|
19
|
-
| Function/Class | Description |
|
|
20
|
-
|--------|------|
|
|
21
|
-
| `createServiceClient` | Factory function for creating a ServiceClient instance. **Recommended over using the class constructor directly.** |
|
|
22
|
-
| `ServiceClient` | Main service client class. Provides integrated connection management, RPC calls, events, files, and authentication. |
|
|
23
|
-
| `createServiceTransport` | Factory function for creating a ServiceTransport instance |
|
|
24
|
-
| `ServiceTransport` | Message transport layer. Handles request/response matching, progress tracking, and protocol encoding/decoding. |
|
|
25
|
-
| `createSocketProvider` | Factory function for creating a SocketProvider instance |
|
|
26
|
-
| `SocketProvider` | WebSocket connection management. Handles heartbeat, auto-reconnection, and connection state events. |
|
|
27
|
-
| `createClientProtocolWrapper` | Factory function for creating a ClientProtocolWrapper instance |
|
|
28
|
-
| `ClientProtocolWrapper` | Protocol wrapper. Automatically selects main thread/Web Worker for encoding/decoding based on data size. |
|
|
29
|
-
|
|
30
|
-
### Feature Functions and Classes
|
|
31
|
-
|
|
32
|
-
| Function/Class | Description |
|
|
33
|
-
|--------|------|
|
|
34
|
-
| `createEventClient` | Factory function for creating an EventClient instance |
|
|
35
|
-
| `EventClient` | Server event subscription/publishing. Supports automatic listener recovery on reconnection. |
|
|
36
|
-
| `createFileClient` | Factory function for creating a FileClient instance |
|
|
37
|
-
| `FileClient` | Handles HTTP-based file upload/download. |
|
|
38
|
-
| `createOrmClientConnector` | Factory function for creating an OrmClientConnector instance |
|
|
39
|
-
| `OrmClientConnector` | ORM remote connection connector. Supports transaction/non-transaction connections. |
|
|
40
|
-
| `OrmClientDbContextExecutor` | ORM DbContext remote executor. Calls server's `OrmService` via RPC. |
|
|
41
|
-
|
|
42
|
-
### Types/Interfaces
|
|
43
|
-
|
|
44
|
-
| Type | Description |
|
|
45
|
-
|------|------|
|
|
46
|
-
| `ServiceConnectionConfig` | Server connection config (host, port, ssl, maxReconnectCount) |
|
|
47
|
-
| `ServiceProgress` | Request/response progress callback |
|
|
48
|
-
| `ServiceProgressState` | Progress state (uuid, totalSize, completedSize) |
|
|
49
|
-
| `SocketProviderEvents` | Event map for SocketProvider (message, state) |
|
|
50
|
-
| `ServiceTransportEvents` | Event map for ServiceTransport (reload, event) |
|
|
51
|
-
| `OrmConnectConfig<T>` | ORM connection config (DbContext type, connection options, DB/schema override) |
|
|
52
|
-
| `RemoteService<T>` | Utility type that wraps all method return types of a service interface with `Promise` |
|
|
53
|
-
|
|
54
|
-
## Usage
|
|
55
|
-
|
|
56
|
-
### Basic Connection and Service Call
|
|
57
|
-
|
|
58
|
-
```typescript
|
|
59
|
-
import { createServiceClient } from "@simplysm/service-client";
|
|
60
|
-
|
|
61
|
-
// Create client (recommended: use factory function)
|
|
62
|
-
const client = createServiceClient("my-app", {
|
|
63
|
-
host: "localhost",
|
|
64
|
-
port: 8080,
|
|
65
|
-
ssl: false,
|
|
66
|
-
maxReconnectCount: 10, // Max reconnection attempts (default: 10, 0 means no reconnection)
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
// Connect to server
|
|
70
|
-
await client.connect();
|
|
71
|
-
|
|
72
|
-
// Check connection status
|
|
73
|
-
console.log(client.connected); // true
|
|
74
|
-
console.log(client.hostUrl); // "http://localhost:8080"
|
|
75
|
-
console.log(client.name); // "my-app"
|
|
76
|
-
|
|
77
|
-
// Direct RPC call
|
|
78
|
-
const result = await client.send("MyService", "getUsers", [{ page: 1 }]);
|
|
79
|
-
|
|
80
|
-
// Close connection
|
|
81
|
-
await client.close();
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### Type-Safe Service Call (getService)
|
|
85
|
-
|
|
86
|
-
`getService<T>()` uses `Proxy` to provide type-safe remote calls to service interfaces.
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
// Server-side service definition
|
|
90
|
-
import { defineService } from "@simplysm/service-server";
|
|
91
|
-
|
|
92
|
-
export const UserService = defineService("UserService", (ctx) => ({
|
|
93
|
-
getUsers: async (filter: { page: number }): Promise<User[]> => {
|
|
94
|
-
// ...
|
|
95
|
-
},
|
|
96
|
-
createUser: async (data: CreateUserDto): Promise<number> => {
|
|
97
|
-
// ...
|
|
98
|
-
},
|
|
99
|
-
deleteUser: async (id: number): Promise<void> => {
|
|
100
|
-
// ...
|
|
101
|
-
},
|
|
102
|
-
}));
|
|
103
|
-
|
|
104
|
-
// Export type for client-side usage
|
|
105
|
-
export type UserServiceMethods = import("@simplysm/service-server").ServiceMethods<typeof UserService>;
|
|
106
|
-
|
|
107
|
-
// Client-side usage
|
|
108
|
-
import type { UserServiceMethods } from "./server/services/user-service";
|
|
109
|
-
|
|
110
|
-
const userService = client.getService<UserServiceMethods>("UserService");
|
|
111
|
-
|
|
112
|
-
// Parameter/return types are automatically inferred on method calls
|
|
113
|
-
const users = await userService.getUsers({ page: 1 }); // users: User[]
|
|
114
|
-
const newId = await userService.createUser({ name: "test" }); // newId: number
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
`ServiceMethods<T>` extracts method types from a service definition. `RemoteService<T>` wraps all method return types with `Promise` (methods already returning `Promise` are not double-wrapped).
|
|
118
|
-
|
|
119
|
-
### Authentication
|
|
120
|
-
|
|
121
|
-
```typescript
|
|
122
|
-
// Send auth token after server connection
|
|
123
|
-
await client.connect();
|
|
124
|
-
await client.auth("jwt-token-here");
|
|
125
|
-
|
|
126
|
-
// Automatically re-authenticated on reconnection
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
Tokens stored after `auth()` calls are automatically resent to the server on WebSocket reconnection.
|
|
130
|
-
|
|
131
|
-
### Connection State Monitoring
|
|
132
|
-
|
|
133
|
-
`ServiceClient` extends `EventEmitter` and supports the following events.
|
|
134
|
-
|
|
135
|
-
| Event | Type | Description |
|
|
136
|
-
|--------|------|------|
|
|
137
|
-
| `state` | `"connected" \| "closed" \| "reconnecting"` | Connection state change |
|
|
138
|
-
| `request-progress` | `ServiceProgressState` | Request transmission progress |
|
|
139
|
-
| `response-progress` | `ServiceProgressState` | Response reception progress |
|
|
140
|
-
| `reload` | `Set<string>` | File change notification from server (dev mode HMR) |
|
|
141
|
-
|
|
142
|
-
```typescript
|
|
143
|
-
// Monitor connection state changes
|
|
144
|
-
client.on("state", (state) => {
|
|
145
|
-
if (state === "connected") {
|
|
146
|
-
console.log("Connected to server");
|
|
147
|
-
} else if (state === "reconnecting") {
|
|
148
|
-
console.log("Reconnection in progress...");
|
|
149
|
-
} else if (state === "closed") {
|
|
150
|
-
console.log("Connection closed");
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
// Monitor request/response progress (large messages)
|
|
155
|
-
client.on("request-progress", (state) => {
|
|
156
|
-
const percent = Math.round((state.completedSize / state.totalSize) * 100);
|
|
157
|
-
console.log(`Sending: ${percent}%`);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
client.on("response-progress", (state) => {
|
|
161
|
-
const percent = Math.round((state.completedSize / state.totalSize) * 100);
|
|
162
|
-
console.log(`Receiving: ${percent}%`);
|
|
163
|
-
});
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Individual Request Progress Tracking
|
|
167
|
-
|
|
168
|
-
Track progress of individual requests with the `progress` parameter of the `send()` method.
|
|
169
|
-
|
|
170
|
-
```typescript
|
|
171
|
-
const result = await client.send("DataService", "getLargeData", [query], {
|
|
172
|
-
request: (state) => {
|
|
173
|
-
console.log(`Request sending: ${state.completedSize}/${state.totalSize} bytes`);
|
|
174
|
-
},
|
|
175
|
-
response: (state) => {
|
|
176
|
-
console.log(`Response receiving: ${state.completedSize}/${state.totalSize} bytes`);
|
|
177
|
-
},
|
|
178
|
-
});
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### Event Subscription (Server -> Client)
|
|
182
|
-
|
|
183
|
-
Subscribe to events from the server, and listeners are automatically recovered on reconnection.
|
|
184
|
-
|
|
185
|
-
```typescript
|
|
186
|
-
import { defineEvent } from "@simplysm/service-common";
|
|
187
|
-
|
|
188
|
-
// Event definition (shared between server/client)
|
|
189
|
-
export const SharedDataChangeEvent = defineEvent<
|
|
190
|
-
{ name: string; filter: unknown },
|
|
191
|
-
(string | number)[] | undefined
|
|
192
|
-
>("SharedDataChangeEvent");
|
|
193
|
-
|
|
194
|
-
// Subscribe to event
|
|
195
|
-
const listenerKey = await client.addEventListener(
|
|
196
|
-
SharedDataChangeEvent,
|
|
197
|
-
{ name: "users", filter: null },
|
|
198
|
-
async (data) => {
|
|
199
|
-
console.log("Data changed:", data);
|
|
200
|
-
},
|
|
201
|
-
);
|
|
202
|
-
|
|
203
|
-
// Unsubscribe from event
|
|
204
|
-
await client.removeEventListener(listenerKey);
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
### Event Publishing (Client -> Server -> Other Clients)
|
|
208
|
-
|
|
209
|
-
```typescript
|
|
210
|
-
import { defineEvent } from "@simplysm/service-common";
|
|
211
|
-
|
|
212
|
-
export const SharedDataChangeEvent = defineEvent<
|
|
213
|
-
{ name: string; filter: unknown },
|
|
214
|
-
(string | number)[] | undefined
|
|
215
|
-
>("SharedDataChangeEvent");
|
|
216
|
-
|
|
217
|
-
// Publish event to listeners matching specific conditions
|
|
218
|
-
await client.emitToServer(
|
|
219
|
-
SharedDataChangeEvent,
|
|
220
|
-
(info) => info.name === "users", // Target filter
|
|
221
|
-
[1, 2, 3], // Data to send
|
|
222
|
-
);
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
The server finds listeners matching the `infoSelector` condition in the registered listener list and delivers the event.
|
|
226
|
-
|
|
227
|
-
### File Upload
|
|
228
|
-
|
|
229
|
-
File upload is handled via HTTP POST requests and requires an authentication token.
|
|
230
|
-
|
|
231
|
-
```typescript
|
|
232
|
-
// Authentication required
|
|
233
|
-
await client.auth("jwt-token");
|
|
234
|
-
|
|
235
|
-
// Upload with browser File object
|
|
236
|
-
const fileInput = document.querySelector("input[type=file]") as HTMLInputElement;
|
|
237
|
-
const results = await client.uploadFile(fileInput.files!);
|
|
238
|
-
|
|
239
|
-
// Upload with custom data
|
|
240
|
-
const results = await client.uploadFile([
|
|
241
|
-
{ name: "data.json", data: JSON.stringify({ key: "value" }) },
|
|
242
|
-
{ name: "image.png", data: imageBlob },
|
|
243
|
-
]);
|
|
244
|
-
|
|
245
|
-
// Upload results
|
|
246
|
-
for (const result of results) {
|
|
247
|
-
console.log(result.path); // Server storage path
|
|
248
|
-
console.log(result.filename); // Original filename
|
|
249
|
-
console.log(result.size); // File size (bytes)
|
|
250
|
-
}
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### File Download
|
|
254
|
-
|
|
255
|
-
```typescript
|
|
256
|
-
// Download file from server's relative path
|
|
257
|
-
const buffer = await client.downloadFileBuffer("/uploads/2024/file.pdf");
|
|
258
|
-
// buffer: Uint8Array
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
### ORM Remote Access
|
|
262
|
-
|
|
263
|
-
Access the database through the server's ORM service. Transactions are automatically managed.
|
|
264
|
-
|
|
265
|
-
```typescript
|
|
266
|
-
import { createOrmClientConnector } from "@simplysm/service-client";
|
|
267
|
-
import type { OrmConnectConfig } from "@simplysm/service-client";
|
|
268
|
-
import { DbContext } from "@simplysm/orm-common";
|
|
269
|
-
|
|
270
|
-
const connector = createOrmClientConnector(client);
|
|
271
|
-
|
|
272
|
-
// Connect with transaction (auto rollback on error)
|
|
273
|
-
await connector.connect(
|
|
274
|
-
{
|
|
275
|
-
dbContextDef: MyDbContext,
|
|
276
|
-
connOpt: { configName: "default" },
|
|
277
|
-
dbContextOpt: { database: "mydb", schema: "dbo" }, // Optional
|
|
278
|
-
},
|
|
279
|
-
async (db) => {
|
|
280
|
-
const users = await db.user().result();
|
|
281
|
-
await db.user().insert([{ name: "test" }]);
|
|
282
|
-
// Auto commit on callback success
|
|
283
|
-
},
|
|
284
|
-
);
|
|
285
|
-
|
|
286
|
-
// Connect without transaction (suitable for read-only operations)
|
|
287
|
-
await connector.connectWithoutTransaction(
|
|
288
|
-
{
|
|
289
|
-
dbContextDef: MyDbContext,
|
|
290
|
-
connOpt: { configName: "default" },
|
|
291
|
-
},
|
|
292
|
-
async (db) => {
|
|
293
|
-
const users = await db.user().result();
|
|
294
|
-
return users;
|
|
295
|
-
},
|
|
296
|
-
);
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
## Detailed API
|
|
300
|
-
|
|
301
|
-
### ServiceConnectionConfig
|
|
302
|
-
|
|
303
|
-
Server connection configuration interface.
|
|
304
|
-
|
|
305
|
-
```typescript
|
|
306
|
-
import type { ServiceConnectionConfig } from "@simplysm/service-client";
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
| Property | Type | Required | Description |
|
|
310
|
-
|------|------|------|------|
|
|
311
|
-
| `host` | `string` | Yes | Server host address |
|
|
312
|
-
| `port` | `number` | Yes | Server port number |
|
|
313
|
-
| `ssl` | `boolean` | No | SSL usage. If `true`, uses `wss://` / `https://` |
|
|
314
|
-
| `maxReconnectCount` | `number` | No | Max reconnection attempts (default: 10). 0 means no reconnection |
|
|
315
|
-
|
|
316
|
-
### createServiceClient
|
|
317
|
-
|
|
318
|
-
Factory function for creating a ServiceClient instance.
|
|
319
|
-
|
|
320
|
-
```typescript
|
|
321
|
-
import { createServiceClient } from "@simplysm/service-client";
|
|
322
|
-
|
|
323
|
-
function createServiceClient(name: string, options: ServiceConnectionConfig): ServiceClient
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
**Parameters:**
|
|
327
|
-
- `name` - Client identifier (used for server-side logging and connection management)
|
|
328
|
-
- `options` - Server connection configuration
|
|
329
|
-
|
|
330
|
-
**Returns:** ServiceClient instance
|
|
331
|
-
|
|
332
|
-
**Example:**
|
|
333
|
-
```typescript
|
|
334
|
-
const client = createServiceClient("my-app", {
|
|
335
|
-
host: "localhost",
|
|
336
|
-
port: 8080,
|
|
337
|
-
ssl: false,
|
|
338
|
-
});
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
### ServiceClient
|
|
342
|
-
|
|
343
|
-
```typescript
|
|
344
|
-
import { ServiceClient } from "@simplysm/service-client";
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
Extends `EventEmitter<ServiceClientEvents>`.
|
|
348
|
-
|
|
349
|
-
| Method/Property | Type / Return Type | Description |
|
|
350
|
-
|-------------|----------|------|
|
|
351
|
-
| `constructor(name, options)` | - | Create client instance. `name` is the client identifier. **Note: Prefer using `createServiceClient()` factory function.** |
|
|
352
|
-
| `name` | `string` | Client identifier (read-only) |
|
|
353
|
-
| `options` | `ServiceConnectionConfig` | Connection configuration (read-only) |
|
|
354
|
-
| `connected` | `boolean` | WebSocket connection status |
|
|
355
|
-
| `hostUrl` | `string` | HTTP URL (e.g., `http://localhost:8080`) |
|
|
356
|
-
| `connect()` | `Promise<void>` | Connect to server via WebSocket |
|
|
357
|
-
| `close()` | `Promise<void>` | Close connection (Graceful Shutdown) |
|
|
358
|
-
| `send(serviceName, methodName, params, progress?)` | `Promise<unknown>` | Remote call to service method |
|
|
359
|
-
| `getService<TService>(serviceName)` | `RemoteService<TService>` | Create type-safe service proxy |
|
|
360
|
-
| `auth(token)` | `Promise<void>` | Send auth token (auto re-auth on reconnection) |
|
|
361
|
-
| `addEventListener(eventDef, info, cb)` | `Promise<string>` | Register event listener. Returns listener key |
|
|
362
|
-
| `removeEventListener(key)` | `Promise<void>` | Remove event listener |
|
|
363
|
-
| `emitToServer(eventDef, infoSelector, data)` | `Promise<void>` | Publish event to other clients through server |
|
|
364
|
-
| `uploadFile(files)` | `Promise<ServiceUploadResult[]>` | File upload (auth required) |
|
|
365
|
-
| `downloadFileBuffer(relPath)` | `Promise<Uint8Array>` | File download |
|
|
366
|
-
|
|
367
|
-
### ServiceProgress / ServiceProgressState
|
|
368
|
-
|
|
369
|
-
Interfaces for tracking progress of large message transmissions.
|
|
370
|
-
|
|
371
|
-
```typescript
|
|
372
|
-
import type { ServiceProgress, ServiceProgressState } from "@simplysm/service-client";
|
|
373
|
-
|
|
374
|
-
interface ServiceProgress {
|
|
375
|
-
request?: (s: ServiceProgressState) => void; // Request transmission progress
|
|
376
|
-
response?: (s: ServiceProgressState) => void; // Response reception progress
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
interface ServiceProgressState {
|
|
380
|
-
uuid: string; // Request unique identifier
|
|
381
|
-
totalSize: number; // Total size (bytes)
|
|
382
|
-
completedSize: number; // Completed size (bytes)
|
|
383
|
-
}
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
### RemoteService\<TService\>
|
|
387
|
-
|
|
388
|
-
Utility type that converts all methods of a service interface so their return types are wrapped with `Promise`. Methods already returning `Promise` are not double-wrapped. Non-function properties become `never`.
|
|
389
|
-
|
|
390
|
-
```typescript
|
|
391
|
-
import type { RemoteService } from "@simplysm/service-client";
|
|
392
|
-
|
|
393
|
-
type RemoteService<TService> = {
|
|
394
|
-
[K in keyof TService]: TService[K] extends (...args: infer P) => infer R
|
|
395
|
-
? (...args: P) => Promise<Awaited<R>>
|
|
396
|
-
: never;
|
|
397
|
-
};
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
### SocketProvider / SocketProviderEvents
|
|
401
|
-
|
|
402
|
-
Low-level WebSocket connection management interface. Not typically used directly — accessed indirectly through `ServiceClient`.
|
|
403
|
-
|
|
404
|
-
```typescript
|
|
405
|
-
import { createSocketProvider } from "@simplysm/service-client";
|
|
406
|
-
import type { SocketProvider, SocketProviderEvents } from "@simplysm/service-client";
|
|
407
|
-
|
|
408
|
-
function createSocketProvider(
|
|
409
|
-
url: string,
|
|
410
|
-
clientName: string,
|
|
411
|
-
maxReconnectCount: number,
|
|
412
|
-
): SocketProvider
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
```typescript
|
|
416
|
-
interface SocketProviderEvents {
|
|
417
|
-
message: Bytes;
|
|
418
|
-
state: "connected" | "closed" | "reconnecting";
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
interface SocketProvider {
|
|
422
|
-
readonly clientName: string;
|
|
423
|
-
readonly connected: boolean;
|
|
424
|
-
on<K extends keyof SocketProviderEvents & string>(type: K, listener: (data: SocketProviderEvents[K]) => void): void;
|
|
425
|
-
off<K extends keyof SocketProviderEvents & string>(type: K, listener: (data: SocketProviderEvents[K]) => void): void;
|
|
426
|
-
connect(): Promise<void>;
|
|
427
|
-
close(): Promise<void>;
|
|
428
|
-
send(data: Bytes): Promise<void>;
|
|
429
|
-
}
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
| Constant | Value | Description |
|
|
433
|
-
|------|-----|------|
|
|
434
|
-
| Heartbeat Timeout | 30s | Connection considered disconnected if no messages for this duration |
|
|
435
|
-
| Heartbeat Interval | 5s | Ping transmission interval |
|
|
436
|
-
| Reconnect Delay | 3s | Reconnection attempt interval |
|
|
437
|
-
|
|
438
|
-
### ServiceTransport / ServiceTransportEvents
|
|
439
|
-
|
|
440
|
-
Message transport layer interface. Handles request/response matching, progress tracking, and protocol encoding/decoding. Not typically used directly — accessed indirectly through `ServiceClient`.
|
|
441
|
-
|
|
442
|
-
```typescript
|
|
443
|
-
import { createServiceTransport } from "@simplysm/service-client";
|
|
444
|
-
import type { ServiceTransport, ServiceTransportEvents } from "@simplysm/service-client";
|
|
445
|
-
|
|
446
|
-
function createServiceTransport(
|
|
447
|
-
socket: SocketProvider,
|
|
448
|
-
protocol: ClientProtocolWrapper,
|
|
449
|
-
): ServiceTransport
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
```typescript
|
|
453
|
-
interface ServiceTransportEvents {
|
|
454
|
-
reload: Set<string>;
|
|
455
|
-
event: { keys: string[]; data: unknown };
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
interface ServiceTransport {
|
|
459
|
-
on<K extends keyof ServiceTransportEvents & string>(type: K, listener: (data: ServiceTransportEvents[K]) => void): void;
|
|
460
|
-
off<K extends keyof ServiceTransportEvents & string>(type: K, listener: (data: ServiceTransportEvents[K]) => void): void;
|
|
461
|
-
send(message: ServiceClientMessage, progress?: ServiceProgress): Promise<unknown>;
|
|
462
|
-
}
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
### ClientProtocolWrapper
|
|
466
|
-
|
|
467
|
-
Protocol wrapper interface. Automatically selects main thread/Web Worker for encoding/decoding based on data size. In browser environments, data exceeding 30KB is automatically processed in a Web Worker to prevent main thread blocking.
|
|
468
|
-
|
|
469
|
-
```typescript
|
|
470
|
-
import { createClientProtocolWrapper } from "@simplysm/service-client";
|
|
471
|
-
import type { ClientProtocolWrapper } from "@simplysm/service-client";
|
|
472
|
-
|
|
473
|
-
function createClientProtocolWrapper(protocol: ServiceProtocol): ClientProtocolWrapper
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
```typescript
|
|
477
|
-
interface ClientProtocolWrapper {
|
|
478
|
-
encode(uuid: string, message: ServiceMessage): Promise<{ chunks: Bytes[]; totalSize: number }>;
|
|
479
|
-
decode(bytes: Bytes): Promise<ServiceMessageDecodeResult<ServiceMessage>>;
|
|
480
|
-
}
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
| Threshold | Condition |
|
|
484
|
-
|--------|------|
|
|
485
|
-
| 30KB or less | Processed directly in main thread |
|
|
486
|
-
| Over 30KB | Delegated to Web Worker (browser environments only) |
|
|
487
|
-
|
|
488
|
-
Worker delegation conditions (during encoding):
|
|
489
|
-
- `Uint8Array` data
|
|
490
|
-
- Strings exceeding 30KB
|
|
491
|
-
- Arrays exceeding 100 elements or arrays containing `Uint8Array`
|
|
492
|
-
|
|
493
|
-
### EventClient
|
|
494
|
-
|
|
495
|
-
Server event subscription/publishing interface. Automatically recovers listeners on reconnection.
|
|
496
|
-
|
|
497
|
-
```typescript
|
|
498
|
-
import { createEventClient } from "@simplysm/service-client";
|
|
499
|
-
import type { EventClient } from "@simplysm/service-client";
|
|
500
|
-
|
|
501
|
-
function createEventClient(transport: ServiceTransport): EventClient
|
|
502
|
-
```
|
|
503
|
-
|
|
504
|
-
```typescript
|
|
505
|
-
interface EventClient {
|
|
506
|
-
addListener<TInfo, TData>(eventDef: ServiceEventDef<TInfo, TData>, info: TInfo, cb: (data: TData) => PromiseLike<void>): Promise<string>;
|
|
507
|
-
removeListener(key: string): Promise<void>;
|
|
508
|
-
emitToServer<TInfo, TData>(eventDef: ServiceEventDef<TInfo, TData>, infoSelector: (item: TInfo) => boolean, data: TData): Promise<void>;
|
|
509
|
-
reRegisterAll(): Promise<void>;
|
|
510
|
-
}
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
| Method | Description |
|
|
514
|
-
|--------|------|
|
|
515
|
-
| `addListener(eventDef, info, cb)` | Register event listener on the server. Returns a listener key for later removal. |
|
|
516
|
-
| `removeListener(key)` | Unregister event listener from the server by key. |
|
|
517
|
-
| `emitToServer(eventDef, infoSelector, data)` | Send event to all server-registered listeners matching `infoSelector`. |
|
|
518
|
-
| `reRegisterAll()` | Re-register all listeners (called automatically on reconnection). |
|
|
519
|
-
|
|
520
|
-
### FileClient
|
|
521
|
-
|
|
522
|
-
HTTP-based file upload/download interface.
|
|
523
|
-
|
|
524
|
-
```typescript
|
|
525
|
-
import { createFileClient } from "@simplysm/service-client";
|
|
526
|
-
import type { FileClient } from "@simplysm/service-client";
|
|
527
|
-
|
|
528
|
-
function createFileClient(hostUrl: string, clientName: string): FileClient
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
```typescript
|
|
532
|
-
interface FileClient {
|
|
533
|
-
download(relPath: string): Promise<Bytes>;
|
|
534
|
-
upload(
|
|
535
|
-
files: File[] | FileList | { name: string; data: BlobPart }[],
|
|
536
|
-
authToken: string,
|
|
537
|
-
): Promise<ServiceUploadResult[]>;
|
|
538
|
-
}
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
### OrmConnectConfig\<TDef\>
|
|
542
|
-
|
|
543
|
-
ORM remote connection configuration interface.
|
|
544
|
-
|
|
545
|
-
```typescript
|
|
546
|
-
import type { OrmConnectConfig } from "@simplysm/service-client";
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
| Property | Type | Required | Description |
|
|
550
|
-
|------|------|------|------|
|
|
551
|
-
| `dbContextDef` | `TDef` | Yes | DbContext class |
|
|
552
|
-
| `connOpt` | `DbConnOptions & { configName: string }` | Yes | DB connection options. `configName` identifies the server-side DB config; `config` can pass additional connection settings |
|
|
553
|
-
| `dbContextOpt` | `{ database: string; schema: string }` | No | Database/schema override |
|
|
554
|
-
|
|
555
|
-
### OrmClientConnector
|
|
556
|
-
|
|
557
|
-
ORM remote connection connector interface. Manages transaction lifecycle over RPC.
|
|
558
|
-
|
|
559
|
-
```typescript
|
|
560
|
-
import { createOrmClientConnector } from "@simplysm/service-client";
|
|
561
|
-
import type { OrmClientConnector } from "@simplysm/service-client";
|
|
562
8
|
|
|
563
|
-
|
|
564
|
-
```
|
|
9
|
+
## Source Index
|
|
565
10
|
|
|
566
|
-
|
|
567
|
-
interface OrmClientConnector {
|
|
568
|
-
connect<TDef extends DbContextDef<any, any, any>, R>(
|
|
569
|
-
config: OrmConnectConfig<TDef>,
|
|
570
|
-
callback: (db: DbContextInstance<TDef>) => Promise<R> | R,
|
|
571
|
-
): Promise<R>;
|
|
572
|
-
connectWithoutTransaction<TDef extends DbContextDef<any, any, any>, R>(
|
|
573
|
-
config: OrmConnectConfig<TDef>,
|
|
574
|
-
callback: (db: DbContextInstance<TDef>) => Promise<R> | R,
|
|
575
|
-
): Promise<R>;
|
|
576
|
-
}
|
|
577
|
-
```
|
|
11
|
+
### Types
|
|
578
12
|
|
|
579
|
-
|
|
|
580
|
-
|
|
581
|
-
| `
|
|
582
|
-
| `
|
|
13
|
+
| Source | Exports | Description | Test |
|
|
14
|
+
|--------|---------|-------------|------|
|
|
15
|
+
| `src/types/connection-config.ts` | `ServiceConnectionConfig` | Host, port, SSL, and reconnect options for a service connection | - |
|
|
16
|
+
| `src/types/progress.types.ts` | `ServiceProgress`, `ServiceProgressState` | Callbacks and state shape for tracking request/response progress | - |
|
|
583
17
|
|
|
584
|
-
###
|
|
18
|
+
### Transport
|
|
585
19
|
|
|
586
|
-
|
|
20
|
+
| Source | Exports | Description | Test |
|
|
21
|
+
|--------|---------|-------------|------|
|
|
22
|
+
| `src/transport/socket-provider.ts` | `SocketProviderEvents`, `SocketProvider`, `createSocketProvider` | WebSocket wrapper with heartbeat, auto-reconnect, and ping/pong | - |
|
|
23
|
+
| `src/transport/service-transport.ts` | `ServiceTransportEvents`, `ServiceTransport`, `createServiceTransport` | Sends protocol messages over a socket and matches responses by UUID | - |
|
|
587
24
|
|
|
588
|
-
|
|
589
|
-
import { OrmClientDbContextExecutor } from "@simplysm/service-client";
|
|
25
|
+
### Protocol
|
|
590
26
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
connect(): Promise<void>
|
|
595
|
-
beginTransaction(isolationLevel?: IsolationLevel): Promise<void>
|
|
596
|
-
commitTransaction(): Promise<void>
|
|
597
|
-
rollbackTransaction(): Promise<void>
|
|
598
|
-
close(): Promise<void>
|
|
599
|
-
executeDefs<T = Record<string, unknown>>(defs: QueryDef[], options?: (ResultMeta | undefined)[]): Promise<T[][]>
|
|
600
|
-
executeParametrized(query: string, params?: unknown[]): Promise<unknown[][]>
|
|
601
|
-
bulkInsert(tableName: string, columnDefs: Record<string, ColumnMeta>, records: Record<string, unknown>[]): Promise<void>
|
|
602
|
-
}
|
|
603
|
-
```
|
|
27
|
+
| Source | Exports | Description | Test |
|
|
28
|
+
|--------|---------|-------------|------|
|
|
29
|
+
| `src/protocol/client-protocol-wrapper.ts` | `ClientProtocolWrapper`, `createClientProtocolWrapper` | Encodes/decodes protocol messages, offloading large payloads to a Web Worker | - |
|
|
604
30
|
|
|
605
|
-
|
|
31
|
+
### Features
|
|
606
32
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
+-- ServiceTransport (message send/receive)
|
|
615
|
-
| +-- ClientProtocolWrapper (encoding/decoding)
|
|
616
|
-
| | +-- ServiceProtocol (main thread)
|
|
617
|
-
| | +-- Web Worker (large data)
|
|
618
|
-
| +-- Request/response matching (UUID-based)
|
|
619
|
-
| +-- Progress tracking
|
|
620
|
-
|
|
|
621
|
-
+-- EventClient (event subscription/publishing)
|
|
622
|
-
| +-- Listener management (registration/removal)
|
|
623
|
-
| +-- Auto recovery on reconnection
|
|
624
|
-
|
|
|
625
|
-
+-- FileClient (HTTP file transfer)
|
|
626
|
-
+-- Upload (FormData, POST)
|
|
627
|
-
+-- Download (GET)
|
|
628
|
-
```
|
|
33
|
+
| Source | Exports | Description | Test |
|
|
34
|
+
|--------|---------|-------------|------|
|
|
35
|
+
| `src/features/event-client.ts` | `EventClient`, `createEventClient` | Registers, removes, and re-registers server-side event listeners | - |
|
|
36
|
+
| `src/features/file-client.ts` | `FileClient`, `createFileClient` | Downloads files via fetch and uploads files via multipart form-data | - |
|
|
37
|
+
| `src/features/orm/orm-connect-config.ts` | `OrmConnectConfig` | Config type pairing a DbContextDef with connection options and DB name | - |
|
|
38
|
+
| `src/features/orm/orm-client-connector.ts` | `OrmClientConnector`, `createOrmClientConnector` | Opens a remote ORM DB context with or without a transaction | - |
|
|
39
|
+
| `src/features/orm/orm-client-db-context-executor.ts` | `OrmClientDbContextExecutor` | DbContextExecutor that delegates all DB operations to the server OrmService | - |
|
|
629
40
|
|
|
630
|
-
|
|
41
|
+
### Main
|
|
631
42
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
-
|
|
635
|
-
- **Large Messages**: Large messages are automatically split/merged by `ServiceProtocol` from `@simplysm/service-common`. Progress can be tracked via `ServiceProgress` callbacks or `ServiceClient` events.
|
|
636
|
-
- **Web Worker**: In browser environments, encoding/decoding of data exceeding 30KB is automatically handled in a Web Worker. In Node.js environments, it's always processed in the main thread.
|
|
637
|
-
- **Foreign Key Error Conversion**: ORM connection errors due to foreign key constraint violations are automatically converted to user-friendly messages.
|
|
43
|
+
| Source | Exports | Description | Test |
|
|
44
|
+
|--------|---------|-------------|------|
|
|
45
|
+
| `src/service-client.ts` | `ServiceClient`, `RemoteService`, `createServiceClient` | Top-level client that composes socket, transport, events, and file features | - |
|
|
638
46
|
|
|
639
47
|
## License
|
|
640
48
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-client.d.ts","sourceRoot":"","sources":["..\\..\\src\\features\\event-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAKvE,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,KAAK,EAAE,KAAK,EACtB,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,EACvC,IAAI,EAAE,KAAK,EACX,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,WAAW,CAAC,IAAI,CAAC,GACrC,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,YAAY,CAAC,KAAK,EAAE,KAAK,EACvB,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,EACvC,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,EACtC,IAAI,EAAE,KAAK,GACV,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,gBAAgB,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"event-client.d.ts","sourceRoot":"","sources":["..\\..\\src\\features\\event-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAKvE,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,KAAK,EAAE,KAAK,EACtB,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,EACvC,IAAI,EAAE,KAAK,EACX,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,WAAW,CAAC,IAAI,CAAC,GACrC,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,YAAY,CAAC,KAAK,EAAE,KAAK,EACvB,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,EACvC,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,EACtC,IAAI,EAAE,KAAK,GACV,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,gBAAgB,GAAG,WAAW,CAsG1E"}
|