@simplysm/service-client 13.0.82 → 13.0.84

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 ADDED
@@ -0,0 +1,68 @@
1
+ # @simplysm/service-client
2
+
3
+ WebSocket-based service client for communicating with `@simplysm/service-server`. Provides RPC-style service calls, real-time event subscriptions, file upload/download, and ORM database access -- all over a single persistent connection with automatic reconnection and heartbeat monitoring.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @simplysm/service-client
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { createServiceClient } from "@simplysm/service-client";
15
+
16
+ // Create and connect
17
+ const client = createServiceClient("my-app", {
18
+ host: "localhost",
19
+ port: 3000,
20
+ });
21
+ await client.connect();
22
+
23
+ // Authenticate
24
+ await client.auth(token);
25
+
26
+ // Call a remote service method
27
+ const userService = client.getService<UserService>("User");
28
+ const users = await userService.getList();
29
+
30
+ // Upload files
31
+ const results = await client.uploadFile(fileList);
32
+
33
+ // Listen to real-time events
34
+ const key = await client.addListener(myEventDef, { roomId: 1 }, async (data) => {
35
+ console.log("Event received:", data);
36
+ });
37
+
38
+ // Clean up
39
+ await client.removeListener(key);
40
+ await client.close();
41
+ ```
42
+
43
+ ## Documentation
44
+
45
+ | Category | File | Description |
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 |
52
+
53
+ ## Architecture
54
+
55
+ ```
56
+ ServiceClient (main facade)
57
+ |-- SocketProvider WebSocket connection + heartbeat + reconnection
58
+ |-- ServiceTransport Request/response multiplexing over socket
59
+ | \-- ClientProtocolWrapper Encode/decode with optional Web Worker
60
+ |-- EventClient Server-sent event subscriptions
61
+ \-- FileClient HTTP file upload/download
62
+ ```
63
+
64
+ ## Dependencies
65
+
66
+ - `@simplysm/core-common` -- EventEmitter, Uuid, transfer utilities
67
+ - `@simplysm/service-common` -- Protocol definitions, message types
68
+ - `@simplysm/orm-common` -- ORM types (for ORM connector feature)
@@ -0,0 +1,190 @@
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.
@@ -0,0 +1,69 @@
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.
@@ -0,0 +1,176 @@
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
+ ```
@@ -0,0 +1,88 @@
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 ADDED
@@ -0,0 +1,61 @@
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 |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/service-client",
3
- "version": "13.0.82",
3
+ "version": "13.0.84",
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.82",
24
- "@simplysm/orm-common": "13.0.82",
25
- "@simplysm/service-common": "13.0.82"
23
+ "@simplysm/core-common": "13.0.84",
24
+ "@simplysm/orm-common": "13.0.84",
25
+ "@simplysm/service-common": "13.0.84"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/ws": "^8.18.1",