react-websocket 3.1.0 → 3.3.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/LICENSE CHANGED
@@ -1,6 +1,7 @@
1
1
  The MIT License (MIT)
2
2
 
3
3
  Copyright (c) 2015 Pim Voeten
4
+ Copyright (c) 2016-2026 Mehmet Kose
4
5
 
5
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
7
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # react-websocket
2
2
 
3
- **Hooks-first WebSocket client for React 18 and 19.** Shared connections, automatic reconnects, a send queue, typed and validated messages, and Suspense, in about 2.5 kB with zero dependencies.
3
+ **Hooks-first WebSocket client for React 18 and 19.** Shared connections, automatic reconnects, a send queue, typed and validated messages, and Suspense, in about 3 kB (min+gzip) with zero dependencies.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/react-websocket.svg)](https://www.npmjs.com/package/react-websocket)
6
6
  [![CI](https://github.com/mehmetkose/react-websocket/actions/workflows/ci.yml/badge.svg)](https://github.com/mehmetkose/react-websocket/actions/workflows/ci.yml)
@@ -13,11 +13,13 @@
13
13
 
14
14
  - **Shared connections.** Components using the same URL share one socket. StrictMode, `<Activity>` and route transitions never open duplicates.
15
15
  - **Auto-reconnect.** Exponential backoff with jitter, plus an immediate retry when the browser comes back online or the tab becomes visible. Optional heartbeats detect dead links.
16
- - **Send queue.** `send()` before the socket is open just works. The message goes out on connect.
16
+ - **Send queue.** `send()` before the socket is open just works. The message goes out on connect. Mark input `volatile` so it's never replayed late, or `key` it so only the newest is sent.
17
17
  - **Typed messages.** `json: true`, your own codec, or validation with any [Standard Schema](https://standardschema.dev) library (zod, valibot, arktype), with inferred types.
18
18
  - **Suspense.** `use(client.ready)` waits for the first connection, and reconnects never flash a fallback.
19
19
  - **Topic subscriptions.** Reference-counted `subscribe`/`unsubscribe` messages that are sent again after every reconnect, so feeds don't silently stop.
20
20
  - **Message state.** Reduce messages into a store, and let each component re-render only when its slice changes.
21
+ - **Requests and latency.** Await replies with timeouts and cancellation, and measure round-trip time and the server's clock for ping displays and synchronized countdowns.
22
+ - **Server requests.** Answer requests from the server, such as an AI agent's, in code for browser-only tools, or from a dialog for human approval. Every request gets exactly one reply, and none is sent to the wrong connection.
21
23
  - **SSR-safe.** Never connects during a server render, hydrates cleanly, and ships a `'use client'` entry for Next.js and other Server Components frameworks.
22
24
  - **Small and typed.** Zero dependencies, ESM + CJS, TypeScript declarations with inline docs, plus a React-free `react-websocket/core` entry.
23
25
 
@@ -112,9 +114,14 @@ function Room() {
112
114
  | `useWebSocketStatus(client)` | The status; re-renders only when it changes |
113
115
  | `useWebSocketTopic(topics, topic)` | Hold topic subscriptions that survive reconnects |
114
116
  | `useWebSocketState(store, selector?)` | Read state reduced from messages; re-renders only when the selection changes |
117
+ | `useWebSocketLatency(latency)` | Round-trip time and server clock offset |
118
+ | `useAgentApproval(responder, method)` | Requests from the server waiting for a person to answer |
115
119
  | `createWebSocket(url, options?)` | A shareable client: `send`, `on`, `connect`, `close`, `reconnect`, `ready`, `getSnapshot`, `subscribe` |
116
120
  | `createWebSocketTopics(client, { subscribe, unsubscribe })` | Topic subscription manager for `useWebSocketTopic` |
117
121
  | `createWebSocketState(client, { initialState, reduce })` | Message-state store for `useWebSocketState` |
122
+ | `createWebSocketRequests(client, { send, reply })` | `request(message)` returns a promise of the reply, with timeouts |
123
+ | `createWebSocketLatency(client, { ping, pong })` | Ping tracker for `useWebSocketLatency`, plus `serverNow()` |
124
+ | `createWebSocketResponder(client, { request, respond, error })` | Answer the server's requests: `onRequest(method, handler)`, or a person through `useAgentApproval` |
118
125
  | `MessageError` | Reported to `onError` when a message fails `parse` or `schema` |
119
126
 
120
127
  | Option | Default | |
@@ -136,7 +143,7 @@ function Room() {
136
143
 
137
144
  - [Shared clients](https://mehmetkose.github.io/react-websocket/guide/shared-clients) · [Messages and types](https://mehmetkose.github.io/react-websocket/guide/messages) · [Reconnecting and heartbeats](https://mehmetkose.github.io/react-websocket/guide/reconnecting)
138
145
  - [Suspense](https://mehmetkose.github.io/react-websocket/guide/suspense) · [Server rendering and Next.js](https://mehmetkose.github.io/react-websocket/guide/ssr) · [StrictMode, Activity and lifecycle](https://mehmetkose.github.io/react-websocket/guide/lifecycle)
139
- - [Authentication](https://mehmetkose.github.io/react-websocket/guide/authentication) · [Performance](https://mehmetkose.github.io/react-websocket/guide/performance) · [Testing](https://mehmetkose.github.io/react-websocket/guide/testing) · [Without React](https://mehmetkose.github.io/react-websocket/guide/without-react)
146
+ - [Authentication](https://mehmetkose.github.io/react-websocket/guide/authentication) · [Performance](https://mehmetkose.github.io/react-websocket/guide/performance) · [Real-time games](https://mehmetkose.github.io/react-websocket/guide/games) · [AI agents](https://mehmetkose.github.io/react-websocket/guide/agents) · [Testing](https://mehmetkose.github.io/react-websocket/guide/testing) · [Without React](https://mehmetkose.github.io/react-websocket/guide/without-react)
140
147
  - [Recipes](https://mehmetkose.github.io/react-websocket/recipes) · [Troubleshooting](https://mehmetkose.github.io/react-websocket/troubleshooting) · [Migrating from v2](https://mehmetkose.github.io/react-websocket/migration)
141
148
 
142
149
  The docs source lives in [`docs/`](docs). Run `npm run docs:dev` to browse it locally.
@@ -153,9 +160,10 @@ The docs source lives in [`docs/`](docs). Run `npm run docs:dev` to browse it lo
153
160
 
154
161
  v2 was a `<Websocket>` class component. v3 replaces it with hooks: `<Websocket url onMessage />` becomes `useWebSocket(url, { onMessage })`, and `ref.sendMessage(msg)` becomes `send(msg)`. See the [migration guide](https://mehmetkose.github.io/react-websocket/migration) for the full mapping.
155
162
 
156
- ## Example
163
+ ## Examples
157
164
 
158
- [`example/`](example) has a Tornado broadcast server and a Vite + React 19 client.
165
+ - [`examples/nextjs`](examples/nextjs) is a demo of every feature in a Next.js App Router app, with its own WebSocket server. Run `npm run example:nextjs` and open http://localhost:3000.
166
+ - [`examples/tornado`](examples/tornado) is a small broadcast chat: a Tornado server and a Vite + React 19 client.
159
167
 
160
168
  ## Contributing
161
169