@exhumer/signalr-client 1.0.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,7 +9,7 @@ ASP.NET Core SignalR client for Node.js. HTTP and WebSocket layers are backed en
9
9
 
10
10
  ## Requirements
11
11
 
12
- - Node.js ≥ 22
12
+ - Node.js ≥ 22.19.0
13
13
  - TypeScript ≥ 5.9 (for consumers using types)
14
14
 
15
15
  ## Installation
@@ -69,6 +69,12 @@ builder.withUrl('https://example.com/hub', {
69
69
 
70
70
  // How often to send a keep-alive ping to the server
71
71
  keepAliveIntervalInMilliseconds: 10_000, // default: 15 000
72
+
73
+ // How long to wait for the SignalR protocol handshake
74
+ handshakeTimeoutInMilliseconds: 15_000, // default: 15 000
75
+
76
+ // Reject an individual incoming transport payload above this size
77
+ maximumReceiveMessageSize: 32 * 1024 * 1024, // default: 32 MiB
72
78
  });
73
79
  ```
74
80
 
@@ -143,6 +149,20 @@ import { FetchHttpClient } from '@exhumer/signalr-client';
143
149
  builder.withHttpClient(new FetchHttpClient());
144
150
  ```
145
151
 
152
+ ### `.withHubProtocol(protocol)`
153
+
154
+ Select the hub wire protocol. JSON is used by default; MessagePack provides a
155
+ compact binary representation and requires server-side MessagePack support.
156
+
157
+ ```ts
158
+ import { HubConnectionBuilder, MsgpackHubProtocol } from '@exhumer/signalr-client';
159
+
160
+ const connection = new HubConnectionBuilder()
161
+ .withUrl('https://example.com/hub')
162
+ .withHubProtocol(new MsgpackHubProtocol())
163
+ .build();
164
+ ```
165
+
146
166
  ### `.build()`
147
167
 
148
168
  Returns a `HubConnection`. Throws if `.withUrl()` was never called.
@@ -197,6 +217,9 @@ sub.dispose();
197
217
  using sub = connection.stream<number>('Counter', 10).subscribe({ next: console.log });
198
218
  ```
199
219
 
220
+ `stream()` sends the invocation immediately. Its result may be subscribed to
221
+ once; items received before `subscribe()` are queued and delivered in order.
222
+
200
223
  ### Receiving hub method calls
201
224
 
202
225
  ```ts
@@ -205,6 +228,9 @@ connection.on('ReceiveMessage', (user: string, msg: string) => {
205
228
  console.log(`${user}: ${msg}`);
206
229
  });
207
230
 
231
+ // If the server requests a result, a handler's return value is sent back.
232
+ connection.on('GetClientName', () => 'node-worker-1');
233
+
208
234
  // Remove a specific handler
209
235
  connection.off('ReceiveMessage', handler);
210
236
 
@@ -284,21 +310,29 @@ const connection = new HubConnectionBuilder()
284
310
 
285
311
  The library currently ships two hub protocol implementations.
286
312
 
287
- **JSON** (default, always active):
313
+ **JSON** (default):
288
314
 
289
315
  ```ts
290
316
  import { JsonHubProtocol } from '@exhumer/signalr-client';
291
317
  ```
292
318
 
293
- `HubConnection` uses `JsonHubProtocol` internally - no configuration required.
319
+ `HubConnection` uses `JsonHubProtocol` when no protocol is configured.
294
320
 
295
- **MessagePack** (optional):
321
+ **MessagePack**:
296
322
 
297
323
  ```ts
298
- import { MsgpackHubProtocol } from '@exhumer/signalr-client';
324
+ import { HubConnectionBuilder, MsgpackHubProtocol } from '@exhumer/signalr-client';
325
+
326
+ const connection = new HubConnectionBuilder()
327
+ .withUrl('https://example.com/hub')
328
+ .withHubProtocol(new MsgpackHubProtocol())
329
+ .build();
299
330
  ```
300
331
 
301
- `MsgpackHubProtocol` is exported for custom transport/protocol use cases. It depends on `@msgpack/msgpack` which is a regular dependency of this package.
332
+ The server must have the ASP.NET Core SignalR MessagePack protocol enabled.
333
+ `MsgpackHubProtocol` depends on `@msgpack/msgpack`, which is a regular
334
+ dependency of this package. Custom protocols can implement `IHubProtocol` and
335
+ be supplied through the same builder method.
302
336
 
303
337
  ---
304
338
 
@@ -308,7 +342,7 @@ Five undici-backed HTTP client implementations are exported. The default (`Dispa
308
342
 
309
343
  | Export | Undici primitive | Notes |
310
344
  |---|---|---|
311
- | `DispatchHttpClient` | `Dispatcher#dispatch()` | Default. Also aliased as `HttpClient`. |
345
+ | `DispatchHttpClient` | `Dispatcher#dispatch()` | Default; explicit pause/resume backpressure for streaming responses. Also aliased as `HttpClient`. |
312
346
  | `RequestHttpClient` | `undici.request()` | |
313
347
  | `FetchHttpClient` | `undici.fetch()` | WHATWG-compatible. |
314
348
  | `StreamHttpClient` | `undici.stream()` | Factory-callback pattern. |
@@ -323,6 +357,26 @@ const client = new DispatchHttpClient();
323
357
  const res = await client.get('https://example.com/api/data');
324
358
  ```
325
359
 
360
+ Every client constructor accepts `HttpClientOptions`, including a dispatcher,
361
+ default timeout, headers, and a buffered-response limit:
362
+
363
+ ```ts
364
+ const client = new DispatchHttpClient({
365
+ maximumResponseBodySize: 8 * 1024 * 1024,
366
+ });
367
+
368
+ await client.post(url, {
369
+ body: new Uint8Array([0x00, 0xff]),
370
+ headers: { 'Content-Type': 'application/octet-stream' },
371
+ });
372
+ ```
373
+
374
+ For streaming responses, `DispatchHttpClient` pauses its undici dispatcher
375
+ when the consumer applies backpressure and resumes it after the stream drains.
376
+ Local benchmarks can be run with `npm run bench:transport`; results depend on
377
+ the runtime and workload. The HTTP client affects WebSocket negotiation and
378
+ startup only—steady-state WebSocket frames bypass it.
379
+
326
380
  ---
327
381
 
328
382
  ## Errors
@@ -447,13 +501,13 @@ npm run bench:protocol
447
501
  npm run bench:transport
448
502
  ```
449
503
 
450
- The build uses [tsup](https://tsup.egoist.dev/) and produces:
504
+ The build uses [tsdown](https://tsdown.dev/) and produces:
451
505
 
452
506
  | File | Format | Purpose |
453
507
  |---|---|---|
454
- | `dist/index.js` | ESM | `import` condition |
508
+ | `dist/index.mjs` | ESM | `import` condition |
455
509
  | `dist/index.cjs` | CJS | `require` condition |
456
- | `dist/index.d.ts` | Types | ESM consumers |
510
+ | `dist/index.d.mts` | Types | ESM consumers |
457
511
  | `dist/index.d.cts` | Types | CJS consumers |
458
512
 
459
513
  Source maps are emitted for all four files.