react-websocket 4.0.0 → 4.18.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 +27 -3
- package/dist/ag-ui.cjs +421 -0
- package/dist/ag-ui.cjs.map +1 -0
- package/dist/ag-ui.d.cts +493 -0
- package/dist/ag-ui.d.ts +171 -0
- package/dist/ag-ui.js +418 -0
- package/dist/ag-ui.js.map +1 -0
- package/dist/core.cjs +689 -153
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +459 -53
- package/dist/core.d.ts +459 -53
- package/dist/core.js +686 -154
- package/dist/core.js.map +1 -1
- package/dist/devtools.cjs +186 -0
- package/dist/devtools.cjs.map +1 -0
- package/dist/devtools.d.cts +32 -0
- package/dist/devtools.d.ts +32 -0
- package/dist/devtools.js +185 -0
- package/dist/devtools.js.map +1 -0
- package/dist/index.cjs +182 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +663 -48
- package/dist/index.d.ts +393 -22
- package/dist/index.js +178 -24
- package/dist/index.js.map +1 -1
- package/dist/outbox.cjs +222 -0
- package/dist/outbox.cjs.map +1 -0
- package/dist/outbox.d.cts +127 -0
- package/dist/outbox.d.ts +127 -0
- package/dist/outbox.js +219 -0
- package/dist/outbox.js.map +1 -0
- package/dist/replay.cjs +324 -0
- package/dist/replay.cjs.map +1 -0
- package/dist/replay.d.cts +124 -0
- package/dist/replay.d.ts +124 -0
- package/dist/replay.js +322 -0
- package/dist/replay.js.map +1 -0
- package/dist/tabs.cjs +336 -0
- package/dist/tabs.cjs.map +1 -0
- package/dist/tabs.d.cts +81 -0
- package/dist/tabs.d.ts +81 -0
- package/dist/tabs.js +335 -0
- package/dist/tabs.js.map +1 -0
- package/dist/timeline.d.cts +1 -216
- package/dist/types-BEecFqIB.d.cts +268 -0
- package/dist/webtransport.cjs +243 -0
- package/dist/webtransport.cjs.map +1 -0
- package/dist/webtransport.d.cts +67 -0
- package/dist/webtransport.d.ts +67 -0
- package/dist/webtransport.js +242 -0
- package/dist/webtransport.js.map +1 -0
- package/package.json +139 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,93 @@
|
|
|
1
1
|
|
|
2
|
+
import { RunPolicy, WebSocketClient, WebSocketRuns } from "./core.js";
|
|
3
|
+
import { RefObject } from "react";
|
|
2
4
|
export * from "./core.js";
|
|
5
|
+
//#region src/ag-ui.d.ts
|
|
6
|
+
/** A tool call on an assistant message, as in AG-UI. */
|
|
7
|
+
interface AgUiToolCall {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly type: 'function';
|
|
10
|
+
readonly function: {
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly arguments: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** A message in an AG-UI thread. */
|
|
16
|
+
interface AgUiMessage {
|
|
17
|
+
readonly id: string;
|
|
18
|
+
readonly role: 'developer' | 'system' | 'assistant' | 'user' | 'tool' | 'reasoning' | 'activity';
|
|
19
|
+
readonly content?: unknown;
|
|
20
|
+
readonly toolCalls?: readonly AgUiToolCall[];
|
|
21
|
+
/** For a `tool` message, the call it answers. */
|
|
22
|
+
readonly toolCallId?: string;
|
|
23
|
+
/** For an `activity` message. */
|
|
24
|
+
readonly activityType?: string;
|
|
25
|
+
readonly [field: string]: unknown;
|
|
26
|
+
}
|
|
27
|
+
/** AG-UI's `RunAgentInput`: what a run starts from. */
|
|
28
|
+
interface RunAgentInput {
|
|
29
|
+
readonly threadId: string;
|
|
30
|
+
readonly runId: string;
|
|
31
|
+
readonly parentRunId?: string;
|
|
32
|
+
readonly state?: unknown;
|
|
33
|
+
readonly messages: readonly AgUiMessage[];
|
|
34
|
+
readonly tools: readonly unknown[];
|
|
35
|
+
readonly context: readonly unknown[];
|
|
36
|
+
readonly forwardedProps: unknown;
|
|
37
|
+
}
|
|
38
|
+
/** A thread's messages and shared state, reduced from AG-UI events. */
|
|
39
|
+
interface AgUiThread<S = unknown> {
|
|
40
|
+
readonly messages: readonly AgUiMessage[];
|
|
41
|
+
/** The shared state, from `STATE_SNAPSHOT` and `STATE_DELTA`. */
|
|
42
|
+
readonly state: S;
|
|
43
|
+
/**
|
|
44
|
+
* `'running'` from `RUN_STARTED`, `'finished'` after `RUN_FINISHED`, `'error'` after
|
|
45
|
+
* `RUN_ERROR`, `'aborted'` when the run was stopped from this side.
|
|
46
|
+
*/
|
|
47
|
+
readonly status: 'idle' | 'running' | 'finished' | 'error' | 'aborted';
|
|
48
|
+
/** The step in progress, between `STEP_STARTED` and `STEP_FINISHED`. */
|
|
49
|
+
readonly step?: string;
|
|
50
|
+
/** From `RUN_ERROR`. */
|
|
51
|
+
readonly error?: {
|
|
52
|
+
readonly message: string;
|
|
53
|
+
readonly code?: string;
|
|
54
|
+
};
|
|
55
|
+
/** From `RUN_FINISHED`. */
|
|
56
|
+
readonly result?: unknown;
|
|
57
|
+
/**
|
|
58
|
+
* A `STATE_DELTA` couldn't be applied. `state` is the last good one, and later deltas are
|
|
59
|
+
* skipped until a `STATE_SNAPSHOT` arrives.
|
|
60
|
+
*/
|
|
61
|
+
readonly stale: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** An AG-UI agent over a WebSocket. Create with {@link createAgUiAgent}. */
|
|
64
|
+
interface AgUiAgent<S> {
|
|
65
|
+
/** The client the runs stream on. */
|
|
66
|
+
readonly client: WebSocketClient<any, any>;
|
|
67
|
+
/** The runs underneath, from `createWebSocketRuns`. */
|
|
68
|
+
readonly runs: WebSocketRuns<RunAgentInput, AgUiThread<S>>;
|
|
69
|
+
/**
|
|
70
|
+
* Start a run with the thread so far plus `input.messages`, which show up in the thread right
|
|
71
|
+
* away. A run that's still streaming is aborted first. Returns the run's id.
|
|
72
|
+
*/
|
|
73
|
+
run(input?: {
|
|
74
|
+
messages?: readonly AgUiMessage[];
|
|
75
|
+
tools?: readonly unknown[];
|
|
76
|
+
context?: readonly unknown[];
|
|
77
|
+
forwardedProps?: unknown;
|
|
78
|
+
}, options?: {
|
|
79
|
+
policy?: RunPolicy;
|
|
80
|
+
}): string;
|
|
81
|
+
/** Stop the run that's streaming, if any. */
|
|
82
|
+
abort(): void;
|
|
83
|
+
/** The thread as of the latest run. The same object until it changes. */
|
|
84
|
+
getSnapshot(): AgUiThread<S>;
|
|
85
|
+
/** Get notified when the thread changes. Compatible with `useSyncExternalStore`. */
|
|
86
|
+
subscribe(listener: () => void): () => void;
|
|
87
|
+
/** Stop following runs, and release the connection. */
|
|
88
|
+
dispose(): void;
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
3
91
|
//#region src/types.d.ts
|
|
4
92
|
/**
|
|
5
93
|
* Where to connect: a URL, or a function that returns one (sync or async).
|
|
@@ -22,7 +110,8 @@ type UrlSource = string | (() => string | Promise<string>);
|
|
|
22
110
|
* - `open`: connected. `send()` goes out immediately.
|
|
23
111
|
* - `reconnecting`: the connection dropped (or an attempt failed) and a retry is scheduled or in progress.
|
|
24
112
|
* - `closed`: stopped for good, by `close()` or after giving up on reconnecting.
|
|
25
|
-
* It stays closed until `connect()` or `reconnect()` is called, or every hook unmounts.
|
|
113
|
+
* It stays closed until `connect()` or `reconnect()` is called, or every hook unmounts. If
|
|
114
|
+
* nothing held it when it stopped, the next hook to mount starts it again.
|
|
26
115
|
*/
|
|
27
116
|
type Status = 'idle' | 'connecting' | 'open' | 'reconnecting' | 'closed';
|
|
28
117
|
/** The client's state as seen by React. A new object is created on every change. */
|
|
@@ -103,6 +192,45 @@ interface ReconnectOptions {
|
|
|
103
192
|
* @default retryableClose
|
|
104
193
|
*/
|
|
105
194
|
shouldReconnect?: (close: CloseInfo) => boolean;
|
|
195
|
+
/**
|
|
196
|
+
* How long the server asked the client to wait before trying again, in ms, read from the
|
|
197
|
+
* close. Return `undefined` when it didn't ask. The client waits that long plus the usual
|
|
198
|
+
* backoff, so clients told the same delay still spread out, and the `online` and
|
|
199
|
+
* `visibilitychange` events don't cut the wait short.
|
|
200
|
+
*
|
|
201
|
+
* The default, `retryAfter`, reads a `1012` (Service Restart) or `1013` (Try Again Later)
|
|
202
|
+
* close whose reason is a number of seconds, like an HTTP `Retry-After` header. Your own
|
|
203
|
+
* function replaces it.
|
|
204
|
+
*
|
|
205
|
+
* A `1013` close that names no delay still waits longer than other closes: its backoff starts
|
|
206
|
+
* at `maxDelay`.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* import { retryAfter } from 'react-websocket';
|
|
211
|
+
*
|
|
212
|
+
* // Our server also closes with 4429 and the delay in ms as the reason.
|
|
213
|
+
* retryAfter: close => (close.code === 4429 ? Number(close.reason) : retryAfter(close))
|
|
214
|
+
* ```
|
|
215
|
+
* @default retryAfter
|
|
216
|
+
*/
|
|
217
|
+
retryAfter?: (close: CloseInfo) => number | undefined;
|
|
218
|
+
}
|
|
219
|
+
/** Options for `client.migrate()`. */
|
|
220
|
+
interface MigrateOptions {
|
|
221
|
+
/**
|
|
222
|
+
* Where to connect instead: a URL, or a function called before the connection, like the
|
|
223
|
+
* client's own `url`. Later reconnects go there too, until the client is closed, gives up or
|
|
224
|
+
* is torn down.
|
|
225
|
+
* @default the client's current URL
|
|
226
|
+
*/
|
|
227
|
+
url?: UrlSource;
|
|
228
|
+
/**
|
|
229
|
+
* Move at a random moment within this many ms, so that clients asked to move together don't
|
|
230
|
+
* all reconnect at once.
|
|
231
|
+
* @default 0
|
|
232
|
+
*/
|
|
233
|
+
within?: number;
|
|
106
234
|
}
|
|
107
235
|
/** Application-level keep-alive. Useful behind proxies that drop idle connections. */
|
|
108
236
|
interface HeartbeatOptions {
|
|
@@ -118,6 +246,10 @@ interface HeartbeatOptions {
|
|
|
118
246
|
/**
|
|
119
247
|
* If nothing at all arrives within this many ms after a ping, the connection is
|
|
120
248
|
* treated as dead: it closes with code `4000` and reconnects.
|
|
249
|
+
*
|
|
250
|
+
* A ping also goes out right away when the browser comes back online or the tab becomes
|
|
251
|
+
* visible, so a connection that died during sleep is found within `timeout`, not after up
|
|
252
|
+
* to `interval` more.
|
|
121
253
|
*/
|
|
122
254
|
timeout?: number;
|
|
123
255
|
}
|
|
@@ -162,11 +294,19 @@ interface SendOptions {
|
|
|
162
294
|
* ```
|
|
163
295
|
*/
|
|
164
296
|
maxBuffered?: number;
|
|
297
|
+
/**
|
|
298
|
+
* Drop the message instead of sending it if it has been queued for longer than this many
|
|
299
|
+
* ms, for messages that go stale during a long outage, such as "typing" or a price quote.
|
|
300
|
+
* Overrides `queue.maxAge`. Checked when the socket opens and whenever another message is
|
|
301
|
+
* queued; `onDrop` is called then.
|
|
302
|
+
*/
|
|
303
|
+
maxAge?: number;
|
|
165
304
|
/**
|
|
166
305
|
* Called if the message is dropped from the queue without being sent: replaced by a
|
|
167
|
-
* newer message with the same `key`,
|
|
168
|
-
* queue is cleared because the client closed or gave up, or when `send()`
|
|
169
|
-
* message right away (`volatile` while not open, or `maxBuffered`) and returns
|
|
306
|
+
* newer message with the same `key`, evicted by `queue.limit`, or older than `maxAge`. Not
|
|
307
|
+
* called when the queue is cleared because the client closed or gave up, or when `send()`
|
|
308
|
+
* drops the message right away (`volatile` while not open, or `maxBuffered`) and returns
|
|
309
|
+
* `false`.
|
|
170
310
|
*/
|
|
171
311
|
onDrop?: () => void;
|
|
172
312
|
}
|
|
@@ -179,6 +319,13 @@ interface QueueOptions {
|
|
|
179
319
|
* @default 100
|
|
180
320
|
*/
|
|
181
321
|
limit?: number;
|
|
322
|
+
/**
|
|
323
|
+
* Drop a queued message instead of sending it once it has waited longer than this many ms,
|
|
324
|
+
* calling its `onDrop`. A message's own `maxAge` overrides it. Checked when the socket opens
|
|
325
|
+
* and whenever another message is queued.
|
|
326
|
+
* @default Infinity
|
|
327
|
+
*/
|
|
328
|
+
maxAge?: number;
|
|
182
329
|
}
|
|
183
330
|
/**
|
|
184
331
|
* The minimal [Standard Schema v1](https://standardschema.dev) interface, implemented
|
|
@@ -326,7 +473,7 @@ interface EventMap<In> {
|
|
|
326
473
|
* @typeParam In - Type of incoming messages.
|
|
327
474
|
* @typeParam Out - Type accepted by `send()`.
|
|
328
475
|
*/
|
|
329
|
-
interface WebSocketClient<In = unknown, Out = unknown> {
|
|
476
|
+
interface WebSocketClient$1<In = unknown, Out = unknown> {
|
|
330
477
|
/** The URL (or URL function) the client was created with. */
|
|
331
478
|
readonly url: UrlSource;
|
|
332
479
|
/**
|
|
@@ -377,7 +524,10 @@ interface WebSocketClient<In = unknown, Out = unknown> {
|
|
|
377
524
|
/**
|
|
378
525
|
* Close the connection and stop reconnecting. The status becomes `closed` and the
|
|
379
526
|
* send queue is cleared. Mounted hooks stay mounted; call `connect()` or `reconnect()`
|
|
380
|
-
* to start again.
|
|
527
|
+
* to start again. Closed while no hook holds it, the next hook to mount starts it again.
|
|
528
|
+
*
|
|
529
|
+
* Like `WebSocket.close()`, it throws for a code or reason the socket rejects (browsers take
|
|
530
|
+
* `1000` or `3000`–`4999`, and a reason up to 123 bytes), and then nothing has changed.
|
|
381
531
|
* @param code - Close code. @default 1000
|
|
382
532
|
*/
|
|
383
533
|
close(code?: number, reason?: string): void;
|
|
@@ -386,6 +536,28 @@ interface WebSocketClient<In = unknown, Out = unknown> {
|
|
|
386
536
|
* backoff. Also restarts a `closed` client.
|
|
387
537
|
*/
|
|
388
538
|
reconnect(): void;
|
|
539
|
+
/**
|
|
540
|
+
* Move to a new connection without a gap, for example when the server asks its clients to
|
|
541
|
+
* before a deploy. At a random moment within `options.within` ms, it opens a new connection
|
|
542
|
+
* (to `options.url`, if given) and, once that one is open, closes the current one with code
|
|
543
|
+
* `1000`. Until then the current connection keeps working, so the status stays `open` and
|
|
544
|
+
* `send()` doesn't queue.
|
|
545
|
+
*
|
|
546
|
+
* `open` listeners run for the new connection, as after any reconnect, so handshakes and
|
|
547
|
+
* topic subscriptions are sent again. Requests the old connection hadn't answered fail as on
|
|
548
|
+
* a lost connection. If the new connection fails before opening, the current one stays. If
|
|
549
|
+
* the client isn't open when the moment comes, only the URL changes, for the next attempt.
|
|
550
|
+
* A later call replaces one that hasn't moved yet.
|
|
551
|
+
*
|
|
552
|
+
* @example
|
|
553
|
+
* ```ts
|
|
554
|
+
* // The server sends { type: 'reconnect', within: 30000 } before it shuts down.
|
|
555
|
+
* live.on('message', message => {
|
|
556
|
+
* if (message.type === 'reconnect') live.migrate({ within: message.within, url: message.url });
|
|
557
|
+
* });
|
|
558
|
+
* ```
|
|
559
|
+
*/
|
|
560
|
+
migrate(options?: MigrateOptions): void;
|
|
389
561
|
/**
|
|
390
562
|
* Hold the connection open until the returned function is called. This is what the
|
|
391
563
|
* hooks use; call it yourself to integrate with non-React code.
|
|
@@ -408,7 +580,7 @@ interface Latency {
|
|
|
408
580
|
/** Round-trip time and server clock offset for one client. Create with {@link createWebSocketLatency}. */
|
|
409
581
|
interface WebSocketLatency {
|
|
410
582
|
/** The client being measured. Hooks reading the latency keep it connected. */
|
|
411
|
-
readonly client: WebSocketClient<any, any>;
|
|
583
|
+
readonly client: WebSocketClient$1<any, any>;
|
|
412
584
|
/** The current {@link Latency}. Returns the same object until it changes. */
|
|
413
585
|
getSnapshot(): Latency;
|
|
414
586
|
/** Called whenever a measurement changes. Compatible with `useSyncExternalStore`. */
|
|
@@ -421,6 +593,83 @@ interface WebSocketLatency {
|
|
|
421
593
|
dispose(): void;
|
|
422
594
|
}
|
|
423
595
|
//#endregion
|
|
596
|
+
//#region src/outbox.d.ts
|
|
597
|
+
/** What an outbox stores for each message. */
|
|
598
|
+
interface OutboxRecord<M = unknown> {
|
|
599
|
+
/** The message's idempotency key, sent with it every time. */
|
|
600
|
+
readonly id: string;
|
|
601
|
+
/** The message, as passed to `add()`. */
|
|
602
|
+
readonly message: M;
|
|
603
|
+
/** When it was added, from `Date.now()`. Entries are sent in this order. */
|
|
604
|
+
readonly createdAt: number;
|
|
605
|
+
}
|
|
606
|
+
/** A message waiting in the outbox. */
|
|
607
|
+
interface OutboxEntry<M = unknown> extends OutboxRecord<M> {
|
|
608
|
+
/** Sent on the current connection, and waiting for the server's ack. */
|
|
609
|
+
readonly sent: boolean;
|
|
610
|
+
}
|
|
611
|
+
/** A persistent outbox on one client. Create with {@link createWebSocketOutbox}. */
|
|
612
|
+
interface WebSocketOutbox<M> {
|
|
613
|
+
/** The client the entries are sent on. */
|
|
614
|
+
readonly client: WebSocketClient<any, any>;
|
|
615
|
+
/**
|
|
616
|
+
* Resolves once the entries stored by an earlier page load are back in the outbox, and
|
|
617
|
+
* rejects if they couldn't be loaded. Nothing is sent before.
|
|
618
|
+
*/
|
|
619
|
+
readonly ready: Promise<void>;
|
|
620
|
+
/**
|
|
621
|
+
* Add a message and send it as soon as the socket is open. Resolves with its id once it's
|
|
622
|
+
* stored, and rejects if storing failed; the entry is still sent from memory then, but won't
|
|
623
|
+
* survive a reload. Without `ack`, one sent right away isn't stored, and resolves at once.
|
|
624
|
+
* @param id - The idempotency key, e.g. an order number. A new random one by default.
|
|
625
|
+
*/
|
|
626
|
+
add(message: M, id?: string): Promise<string>;
|
|
627
|
+
/**
|
|
628
|
+
* Remove an entry without sending it again, e.g. when the user cancels it. Other tabs using
|
|
629
|
+
* the same `name` drop it too.
|
|
630
|
+
*/
|
|
631
|
+
remove(id: string): Promise<void>;
|
|
632
|
+
/**
|
|
633
|
+
* Remove every entry at once, including ones other tabs stored, e.g. on logout. Other tabs
|
|
634
|
+
* using the same `name` drop theirs too. Resolves once they're deleted from storage.
|
|
635
|
+
*/
|
|
636
|
+
clear(): Promise<void>;
|
|
637
|
+
/** The waiting entries, oldest first. A new array on every change. */
|
|
638
|
+
getSnapshot(): readonly OutboxEntry<M>[];
|
|
639
|
+
/** Get notified when the entries change. Compatible with `useSyncExternalStore`. */
|
|
640
|
+
subscribe(listener: () => void): () => void;
|
|
641
|
+
/** Stop sending and listening, and release the connection. Stored entries stay stored. */
|
|
642
|
+
dispose(): void;
|
|
643
|
+
}
|
|
644
|
+
//#endregion
|
|
645
|
+
//#region src/presence.d.ts
|
|
646
|
+
/** Another client's shared state, such as its cursor or what it's selected. */
|
|
647
|
+
interface PresencePeer<P> {
|
|
648
|
+
/** The peer's id, as the server reports it. */
|
|
649
|
+
readonly peer: string;
|
|
650
|
+
readonly state: P;
|
|
651
|
+
/** When its state last arrived, from `Date.now()`. */
|
|
652
|
+
readonly updatedAt: number;
|
|
653
|
+
}
|
|
654
|
+
/** Shared per-peer state that expires. Create with {@link createWebSocketPresence}. */
|
|
655
|
+
interface WebSocketPresence<P> {
|
|
656
|
+
/** The client the state is shared on. */
|
|
657
|
+
readonly client: WebSocketClient$1<any, any>;
|
|
658
|
+
/**
|
|
659
|
+
* Share this client's state, e.g. on every pointer move. It's sent at most `maxRate` times per
|
|
660
|
+
* second, the newest only, and again on every new connection and every `refresh`.
|
|
661
|
+
*/
|
|
662
|
+
set(state: P): void;
|
|
663
|
+
/** Stop sharing, and send `leave`. `set()` shares again. */
|
|
664
|
+
leave(): void;
|
|
665
|
+
/** The other peers, in the order they first appeared. A new array on every change. */
|
|
666
|
+
getSnapshot(): readonly PresencePeer<P>[];
|
|
667
|
+
/** Get notified when the peers change. Compatible with `useSyncExternalStore`. */
|
|
668
|
+
subscribe(listener: () => void): () => void;
|
|
669
|
+
/** Stop sharing and listening. */
|
|
670
|
+
dispose(): void;
|
|
671
|
+
}
|
|
672
|
+
//#endregion
|
|
424
673
|
//#region src/requests.d.ts
|
|
425
674
|
/** Per-call options for {@link WebSocketRequests.request} and {@link WebSocketRequests.stream}. */
|
|
426
675
|
interface RequestOptions extends SendOptions {
|
|
@@ -435,7 +684,7 @@ interface RequestOptions extends SendOptions {
|
|
|
435
684
|
/** Request/response over one client. Create with {@link createWebSocketRequests}. */
|
|
436
685
|
interface WebSocketRequests<Req, In> {
|
|
437
686
|
/** The client requests are sent on. */
|
|
438
|
-
readonly client: WebSocketClient<any, any>;
|
|
687
|
+
readonly client: WebSocketClient$1<any, any>;
|
|
439
688
|
/**
|
|
440
689
|
* Send a request and resolve with its reply. Holds the connection until it settles.
|
|
441
690
|
*
|
|
@@ -505,7 +754,7 @@ type RequestHandler<P = unknown, R = unknown> = (params: P, request: IncomingReq
|
|
|
505
754
|
/** Answers the server's requests on one client. Create with {@link createWebSocketResponder}. */
|
|
506
755
|
interface WebSocketResponder<P = unknown, R = unknown> {
|
|
507
756
|
/** The client requests arrive on. Hooks reading the responder keep it connected. */
|
|
508
|
-
readonly client: WebSocketClient<any, any>;
|
|
757
|
+
readonly client: WebSocketClient$1<any, any>;
|
|
509
758
|
/**
|
|
510
759
|
* Answer requests for `method` until the returned function is called.
|
|
511
760
|
*
|
|
@@ -532,16 +781,65 @@ interface WebSocketResponder<P = unknown, R = unknown> {
|
|
|
532
781
|
dispose(): void;
|
|
533
782
|
}
|
|
534
783
|
//#endregion
|
|
535
|
-
//#region src/
|
|
784
|
+
//#region src/runs.d.ts
|
|
536
785
|
/**
|
|
537
|
-
*
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
* @typeParam S - The state type. Don't use a function type: `setState` treats functions as updaters.
|
|
786
|
+
* What happens to a run when its connection drops: `keep` resumes it on the next connection,
|
|
787
|
+
* for agents that keep working in the background; `cancel` aborts it and tells the server, for
|
|
788
|
+
* a chat answer nobody may be waiting for.
|
|
541
789
|
*/
|
|
790
|
+
type RunPolicy$1 = 'keep' | 'cancel';
|
|
791
|
+
/** Where a run is: streaming events, or ended. */
|
|
792
|
+
type RunStatus = 'streaming' | 'done' | 'error' | 'aborted';
|
|
793
|
+
/** A run's state, reduced from its events. A new object on every change. */
|
|
794
|
+
interface AgentRun<T> {
|
|
795
|
+
readonly runId: string;
|
|
796
|
+
readonly status: RunStatus;
|
|
797
|
+
/** Reduced from the run's events with `reduce`, starting from `initial`. */
|
|
798
|
+
readonly value: T;
|
|
799
|
+
/** What `error` returned for the event that ended the run, when `status` is `'error'`. */
|
|
800
|
+
readonly error: unknown;
|
|
801
|
+
}
|
|
802
|
+
/** Runs that stream events and survive reconnects and reloads. Create with {@link createWebSocketRuns}. */
|
|
803
|
+
interface WebSocketRuns$1<Req, T> {
|
|
804
|
+
/** The client the runs stream on. */
|
|
805
|
+
readonly client: WebSocketClient$1<any, any>;
|
|
806
|
+
/**
|
|
807
|
+
* Start a run and return its `runId`. The start message is sent as soon as the socket is
|
|
808
|
+
* open, and the run is remembered until it ends. `initial` overrides the `initial` option for
|
|
809
|
+
* this run. A `runId` it already knows, streaming or ended, starts nothing: the server starts
|
|
810
|
+
* a run only once per id. `delete()` it first to use the id again.
|
|
811
|
+
*/
|
|
812
|
+
start(request: Req, options?: {
|
|
813
|
+
runId?: string;
|
|
814
|
+
policy?: RunPolicy$1;
|
|
815
|
+
initial?: T;
|
|
816
|
+
}): string;
|
|
817
|
+
/**
|
|
818
|
+
* Follow a run started elsewhere, such as in another tab or before a reload, from its first
|
|
819
|
+
* event. Does nothing for a run it already knows.
|
|
820
|
+
*/
|
|
821
|
+
attach(runId: string, options?: {
|
|
822
|
+
policy?: RunPolicy$1;
|
|
823
|
+
initial?: T;
|
|
824
|
+
}): void;
|
|
825
|
+
/** Stop a streaming run: send `cancel`, and make it `'aborted'`. */
|
|
826
|
+
abort(runId: string): void;
|
|
827
|
+
/** A run's state, or `undefined` for one it doesn't know. The same object until it changes. */
|
|
828
|
+
get(runId: string): AgentRun<T> | undefined;
|
|
829
|
+
/** Every run it knows, oldest first. A new array on every change. */
|
|
830
|
+
list(): readonly AgentRun<T>[];
|
|
831
|
+
/** Get notified when a run changes. Compatible with `useSyncExternalStore`. */
|
|
832
|
+
subscribe(listener: () => void): () => void;
|
|
833
|
+
/** Forget a run, aborting it first if it's streaming. */
|
|
834
|
+
delete(runId: string): void;
|
|
835
|
+
/** Stop following runs, and release the connection. Remembered runs stay remembered. */
|
|
836
|
+
dispose(): void;
|
|
837
|
+
}
|
|
838
|
+
//#endregion
|
|
839
|
+
//#region src/state.d.ts
|
|
542
840
|
interface WebSocketState<S> {
|
|
543
841
|
/** The client whose messages this store reduces. Hooks reading the store keep it connected. */
|
|
544
|
-
readonly client: WebSocketClient<any, any>;
|
|
842
|
+
readonly client: WebSocketClient$1<any, any>;
|
|
545
843
|
/** The `initialState` it was created with. Used for server rendering and hydration. */
|
|
546
844
|
readonly initialState: S;
|
|
547
845
|
/** The current state. Returns the same object until it changes. */
|
|
@@ -560,7 +858,7 @@ interface WebSocketState<S> {
|
|
|
560
858
|
/** Reference-counted topic subscriptions on one client. Create with {@link createWebSocketTopics}. */
|
|
561
859
|
interface WebSocketTopics {
|
|
562
860
|
/** The client the subscription messages are sent on. */
|
|
563
|
-
readonly client: WebSocketClient<any, any>;
|
|
861
|
+
readonly client: WebSocketClient$1<any, any>;
|
|
564
862
|
/**
|
|
565
863
|
* Hold a subscription to `topic`, and the client's connection, until the returned
|
|
566
864
|
* function is called. The release function is safe to call more than once.
|
|
@@ -607,14 +905,15 @@ interface UseWebSocketResult<In, Out> extends Snapshot<In> {
|
|
|
607
905
|
/** Drop the socket and connect again right away. Stable identity. */
|
|
608
906
|
reconnect: () => void;
|
|
609
907
|
/** The underlying client, or `null` when the URL is `null`/`undefined`. */
|
|
610
|
-
client: WebSocketClient<In, Out> | null;
|
|
908
|
+
client: WebSocketClient$1<In, Out> | null;
|
|
611
909
|
}
|
|
612
910
|
/**
|
|
613
911
|
* Connect to a WebSocket and re-render with its status and latest message.
|
|
614
912
|
*
|
|
615
913
|
* - With a URL, every component using the same URL (and `protocols`) shares one
|
|
616
|
-
* connection. Its options come from
|
|
617
|
-
*
|
|
914
|
+
* connection. Its options come from the first of them to mount; in development, a
|
|
915
|
+
* component passing different ones gets a console warning. A render React throws away
|
|
916
|
+
* never decides them.
|
|
618
917
|
* - With a client from `createWebSocket()`, options are the client's; only handlers
|
|
619
918
|
* and `enabled` apply here.
|
|
620
919
|
* - With `null` or `undefined`, nothing connects and the status stays `idle`.
|
|
@@ -634,7 +933,7 @@ interface UseWebSocketResult<In, Out> extends Snapshot<In> {
|
|
|
634
933
|
* ```
|
|
635
934
|
*/
|
|
636
935
|
export declare function useWebSocket<In = unknown, Out = unknown>(url: string | null | undefined, options?: UseWebSocketOptions<In, Out>): UseWebSocketResult<In, Out>;
|
|
637
|
-
export declare function useWebSocket<In, Out>(client: WebSocketClient<In, Out> | null | undefined, options?: WebSocketHandlers<In>): UseWebSocketResult<In, Out>;
|
|
936
|
+
export declare function useWebSocket<In, Out>(client: WebSocketClient$1<In, Out> | null | undefined, options?: WebSocketHandlers<In>): UseWebSocketResult<In, Out>;
|
|
638
937
|
/**
|
|
639
938
|
* Listen to a client's events without re-rendering the component. The listener always
|
|
640
939
|
* sees the latest props and state. Keeps the connection open while mounted.
|
|
@@ -644,7 +943,7 @@ export declare function useWebSocket<In, Out>(client: WebSocketClient<In, Out> |
|
|
|
644
943
|
* useWebSocketEvent(chat, 'message', message => setMessages(list => [...list, message]));
|
|
645
944
|
* ```
|
|
646
945
|
*/
|
|
647
|
-
export declare function useWebSocketEvent<In, K extends keyof EventMap<In>>(client: WebSocketClient<In, any> | null | undefined, type: K, listener: EventMap<In>[K]): void;
|
|
946
|
+
export declare function useWebSocketEvent<In, K extends keyof EventMap<In>>(client: WebSocketClient$1<In, any> | null | undefined, type: K, listener: EventMap<In>[K]): void;
|
|
648
947
|
/**
|
|
649
948
|
* The connection status of a client. Re-renders only when the status changes, not on
|
|
650
949
|
* messages. Keeps the connection open while mounted.
|
|
@@ -654,7 +953,7 @@ export declare function useWebSocketEvent<In, K extends keyof EventMap<In>>(clie
|
|
|
654
953
|
* const status = useWebSocketStatus(chat); // 'idle' | 'connecting' | 'open' | 'reconnecting' | 'closed'
|
|
655
954
|
* ```
|
|
656
955
|
*/
|
|
657
|
-
export declare function useWebSocketStatus(client: WebSocketClient<any, any> | null | undefined): Status;
|
|
956
|
+
export declare function useWebSocketStatus(client: WebSocketClient$1<any, any> | null | undefined): Status;
|
|
658
957
|
/**
|
|
659
958
|
* Read state built from messages by `createWebSocketState`. Re-renders only when the
|
|
660
959
|
* selected value changes (by `isEqual`, default `Object.is`), however often messages
|
|
@@ -693,6 +992,78 @@ export declare function useWebSocketTopic(topics: WebSocketTopics | null | undef
|
|
|
693
992
|
* ```
|
|
694
993
|
*/
|
|
695
994
|
export declare function useWebSocketLatency(latency: WebSocketLatency): Latency;
|
|
995
|
+
/**
|
|
996
|
+
* The messages waiting in an outbox from `react-websocket/outbox`, oldest first, for a "3 orders
|
|
997
|
+
* waiting to sync" banner. Re-renders when they change. `null` lists nothing. On the server the
|
|
998
|
+
* list is empty.
|
|
999
|
+
*
|
|
1000
|
+
* @example
|
|
1001
|
+
* ```tsx
|
|
1002
|
+
* const waiting = useWebSocketOutbox(orders);
|
|
1003
|
+
* if (!waiting.length) return null;
|
|
1004
|
+
* return <p role="status">{waiting.length} orders waiting to sync</p>;
|
|
1005
|
+
* ```
|
|
1006
|
+
*/
|
|
1007
|
+
export declare function useWebSocketOutbox<M>(outbox: WebSocketOutbox<M> | null | undefined): readonly OutboxEntry<M>[];
|
|
1008
|
+
/**
|
|
1009
|
+
* Whether an element is on screen, from an `IntersectionObserver`, for dashboards that stream
|
|
1010
|
+
* full detail only for what's visible: pick a topic with it and pass it to `useWebSocketTopic`,
|
|
1011
|
+
* which switches subscriptions when it changes. `initial` until the first observation, on the
|
|
1012
|
+
* server, and where `IntersectionObserver` doesn't exist.
|
|
1013
|
+
*
|
|
1014
|
+
* @example
|
|
1015
|
+
* ```tsx
|
|
1016
|
+
* const ref = useRef<HTMLElement>(null);
|
|
1017
|
+
* useWebSocketTopic(feeds, useInView(ref) ? `run:${id}:tokens` : `run:${id}:status`);
|
|
1018
|
+
* return <article ref={ref}>…</article>;
|
|
1019
|
+
* ```
|
|
1020
|
+
*/
|
|
1021
|
+
export declare function useInView(ref: RefObject<Element | null>, options?: {
|
|
1022
|
+
rootMargin?: string;
|
|
1023
|
+
threshold?: number;
|
|
1024
|
+
initial?: boolean;
|
|
1025
|
+
}): boolean;
|
|
1026
|
+
/**
|
|
1027
|
+
* The other peers' shared state from `createWebSocketPresence`, such as their cursors.
|
|
1028
|
+
* Re-renders when a peer's state arrives, it leaves, or it times out. Keeps the connection open
|
|
1029
|
+
* while mounted. On the server the list is empty.
|
|
1030
|
+
*
|
|
1031
|
+
* @example
|
|
1032
|
+
* ```tsx
|
|
1033
|
+
* const peers = useWebSocketPresence(cursors);
|
|
1034
|
+
* return peers.map(({ peer, state }) => <Cursor key={peer} x={state.x} y={state.y} />);
|
|
1035
|
+
* ```
|
|
1036
|
+
*/
|
|
1037
|
+
export declare function useWebSocketPresence<P>(presence: WebSocketPresence<P> | null | undefined): readonly PresencePeer<P>[];
|
|
1038
|
+
/**
|
|
1039
|
+
* The thread of an AG-UI agent from `react-websocket/ag-ui`: its messages, shared state and
|
|
1040
|
+
* status, re-rendering on every event.
|
|
1041
|
+
*
|
|
1042
|
+
* @example
|
|
1043
|
+
* ```tsx
|
|
1044
|
+
* const thread = useAgUiAgent(agent);
|
|
1045
|
+
* return thread.messages.map(message => <Message key={message.id} message={message} />);
|
|
1046
|
+
* ```
|
|
1047
|
+
*/
|
|
1048
|
+
export declare function useAgUiAgent<S>(agent: AgUiAgent<S>): AgUiThread<S>;
|
|
1049
|
+
/**
|
|
1050
|
+
* A run from `createWebSocketRuns`, such as an agent's answer: its `value` reduced from the
|
|
1051
|
+
* events so far, and its `status`. Re-renders on every event. A run it doesn't know, such as one
|
|
1052
|
+
* started in another tab, is attached and followed from its first event. `undefined` while the
|
|
1053
|
+
* run is unknown, for a `null` id, and on the server.
|
|
1054
|
+
*
|
|
1055
|
+
* @example
|
|
1056
|
+
* ```tsx
|
|
1057
|
+
* const run = useAgentRun(runs, runId);
|
|
1058
|
+
* return (
|
|
1059
|
+
* <>
|
|
1060
|
+
* <Markdown>{run?.value ?? ''}</Markdown>
|
|
1061
|
+
* {run?.status === 'streaming' && <button onClick={() => runs.abort(runId)}>Stop</button>}
|
|
1062
|
+
* </>
|
|
1063
|
+
* );
|
|
1064
|
+
* ```
|
|
1065
|
+
*/
|
|
1066
|
+
export declare function useAgentRun<T>(runs: WebSocketRuns$1<any, T> | null | undefined, runId: string | null | undefined): AgentRun<T> | undefined;
|
|
696
1067
|
/**
|
|
697
1068
|
* Requests for `method` that a person answers, e.g. an agent asking to run a tool. While mounted,
|
|
698
1069
|
* it registers `method` on the responder without a handler, so new requests wait here instead of
|