redweb 0.15.0 → 0.16.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/CHANGELOG.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 0.16.0
4
+
5
+ - Add opt-in `connectedClients` over the existing RoomRegistry: verified per-connection identity, synchronous room/domain joins with membership rollback, deduplicated presence and checked per-player page projection. Typed handlers bind without changing the browser-safe socket contract. Raw command completion is independent of state updates; only deliberate rejections expose text.
6
+ - Fence obsolete projection failures, bound asynchronous adapters by connection lifetime, and keep a failed recipient from rejecting another player's committed command. Add mock-free socket regressions and unit coverage; no client package changes are needed.
4
7
 
5
8
  ## 0.15.0
6
9
 
package/README.md CHANGED
@@ -11,12 +11,12 @@ Redweb 0.14.0 adds [`defineApp({ pages, sockets, services, port })`](docs/APPLIC
11
11
  Start with a complete, tested counter application:
12
12
 
13
13
  <!-- redweb:setup:start -->
14
- > Documentation for Redweb 0.15.0. Install that exact version when following these examples.
14
+ > Documentation for Redweb 0.16.0. Install that exact version when following these examples.
15
15
 
16
16
  ```sh
17
- npx --yes redweb@0.15.0 init my-realtime --template realtime
17
+ npx --yes redweb@0.16.0 init my-realtime --template realtime
18
18
  cd my-realtime
19
- npm install --save-exact redweb@0.15.0
19
+ npm install --save-exact redweb@0.16.0
20
20
  npm test
21
21
  npm run dev
22
22
  ```
@@ -0,0 +1,65 @@
1
+ # Connected-client implementation verification
2
+
3
+ Date: 2026-09-02. Runtime commit: `e001a58`, branch `codex/connected-clients`.
4
+ This is an unreleased development feature, not the published Redweb 0.15.0 package.
5
+ No client source changes or client publication are required; tests use published
6
+ redweb-client 0.3.0.
7
+
8
+ ## Scope
9
+
10
+ `connectedClients` composes the existing RoomRegistry, bounded authorization,
11
+ projection work, typed socket handlers and private page ownership. It introduces
12
+ no second membership registry. The tutorial consumes it on the companion site's
13
+ `codex/tutorial-connected-clients` branch.
14
+
15
+ ## Passed gates
16
+
17
+ - `npm run pretest`: generated examples, protocol types, development documentation
18
+ and all three TypeScript consumer configurations.
19
+ - 368 unit/integration tests in 25 suites: socket servers/routes, connected clients,
20
+ room access, multiplayer policies/state, protocol/contracts, socket pages,
21
+ distribution, inspection, page access and the existing HTML test directory.
22
+ - Coverage: 100% statements, branches, functions and lines in **ConnectedClients.js,
23
+ RoomRegistry.js, RouteRuntime.js and SocketRoute.js**. Report:
24
+ `coverage/connected-client-rooms`. This is an affected-module claim, not a claim
25
+ that every module in the repository was measured by this command.
26
+ - `npm run verify:live-html:package`: actual tarball installed in isolation;
27
+ counter, chat, reconnect/disconnect, cards, components, JSX, dashboard login,
28
+ generated starters, rendering and development-refresh browser checks passed.
29
+ Browser: headed Google Chrome 152.0.7977.64. Existing bundled HTML-runtime and
30
+ refresh coverage gates also reached 100% in their declared scopes.
31
+ - Production dependency audit: zero reported vulnerabilities.
32
+
33
+ Packed runtime SHA-256 (before adding this evidence document):
34
+ `818bfeb32683089b883bd88f2cef8ac444a8611365a9fe121b4fe2d6b597e540`.
35
+ Package verification report:
36
+ `coverage/packed-browser/8a79c650-cf59-460b-b024-ad791406147f`.
37
+ The archive retains the development checkout's 0.15.0 manifest version; it is
38
+ **not** the npm release bearing that version and must not be published over it.
39
+
40
+ ## Real-network regressions
41
+
42
+ Independent tabs receive separate private pages; presence counts unique identities
43
+ and reacts to the last tab disconnecting. Tests also cover capacity before domain
44
+ commit, rejected-join membership rollback, room isolation, authorization revoked
45
+ during validation/projection, stale successful and failed projections, failing
46
+ recipients, page-only groups, raw clients and overlapping commands.
47
+
48
+ Senior critic findings were fixed and regression-tested:
49
+
50
+ 1. A stale authorization/projection failure cannot disconnect a newer valid view.
51
+ 2. Raw command completion is independent of superseded state projections.
52
+ 3. Raw rejection adapters are bounded and cancel when the connection closes.
53
+
54
+ No soak or long fixed-observation-time tests were run. Test timeouts are failure
55
+ deadlines. Application callbacks still must validate before mutating domain state;
56
+ membership rollback is not an arbitrary application/database transaction.
57
+
58
+ ## Release boundary
59
+
60
+ The implementation above was tested as unreleased. Release preparation now targets
61
+ **0.16.0**, with matching package/lock metadata and a generated immutable release
62
+ catalogue. This preparation does not publish the package or change runtime code.
63
+ After publication, update the site's dependency pins, lockfiles and catalogue;
64
+ remove development-preview notices and retest the archive against registry packages
65
+ before manual deployment. Immutable published documentation snapshots are unchanged.
@@ -1,5 +1,78 @@
1
1
  # Server-side TSX for custom socket routes
2
2
 
3
+ ## Connected clients (0.16.0)
4
+
5
+ The following convenience layer requires Redweb **0.16.0**; it is not in Redweb 0.15.0.
6
+ It uses existing redweb-client 0.3.0 without a client upgrade.
7
+
8
+ `connectedClients({ identity, page, project })` creates one route-owned group.
9
+ Register it as `connections` in `SocketRoute`; rooms and handler drain tracking
10
+ are enabled by default. Create a fresh group inside each application factory.
11
+ It reuses RoomRegistry capacity, authorization and disconnect cleanup, not a second
12
+ membership map. Normal raw SocketRoute/SocketContract APIs remain unchanged.
13
+
14
+ ```ts
15
+ const players = connectedClients({
16
+ identity: context => account(context.request),
17
+ page: () => GamePage,
18
+ project: (player, room, online) => ({
19
+ game: games.resume(room, player.identity).snapshot(player.identity),
20
+ online,
21
+ }),
22
+ });
23
+ const match = players.bind(contract);
24
+ const Join = match.handler('join', (player, { room }) =>
25
+ player.join(room, () => games.join(room, player.identity)));
26
+ ```
27
+
28
+ This is a composition excerpt: the application supplies `account`, `games`, the
29
+ typed `contract`, and decorated `GamePage` state fields. Register the resulting
30
+ handler, contract protocol and `connections: players` on the page's SocketRoute.
31
+ Handler `.with(payload)` bindings keep their inferred input type.
32
+
33
+ The client exposes `identity`, `page`, `rooms`, `room` (exactly one membership),
34
+ `join(room, commit?)`, `leave(room)` and an explicit underlying `socket` escape hatch.
35
+ `players.get(socket)` supports page lifecycle callbacks, and
36
+ `players.refresh(room)` publishes changes made outside a handler. Successful
37
+ handlers automatically refresh their client's current rooms. Room changes batch
38
+ refresh requests; multiple tabs count as one online identity, but receive separate
39
+ private page projections.
40
+
41
+ Identity must remain exactly equal to the admitted principal. The group checks it
42
+ after payload validation and before/after asynchronous projection work. Existing
43
+ page authorization and generation guards remain in force. Access is not granted
44
+ by a button or a room name. The application still defines room access, game rules,
45
+ seat recovery, revisions and durable storage.
46
+
47
+ `join` checks membership capacity/permission before its synchronous domain commit.
48
+ A rejected commit removes newly added membership, but does not remove pre-existing
49
+ membership. Domain operations must validate before changing their own state:
50
+ Redweb cannot roll back arbitrary application or database side effects. Async
51
+ domain commits are rejected; they must not be used as an external transaction.
52
+
53
+ Projection callbacks return partial page state and must be side-effect-free.
54
+ Authorization and projection work use bounded operations (5000ms defaults;
55
+ `authorizationTimeoutMs` and `projectionTimeoutMs` configure them). Disconnect
56
+ cancels delivery; late results and late failures cannot overwrite or disconnect a
57
+ newer generation. Recipient failures do not reject someone else's committed move.
58
+ Cancellation cannot stop arbitrary work inside user callbacks, only its acceptance.
59
+
60
+ Throw `ClientError` only for deliberately public text, or classify domain errors
61
+ with `reject(error): string | undefined`. Unexpected exceptions retain normal
62
+ private server error handling. Optional `errorState(message)` returns page fields
63
+ such as a notice; the framework owns protocol errors and form completion.
64
+
65
+ An optional `raw.update(state)` adapter returns `{ type, payload }` for non-HTML
66
+ clients. Optional `raw.reject(message)` returns an uncorrelated display event.
67
+ Redweb performs the final authorized send, not the adapter. State events are
68
+ uncorrelated; successful raw requests complete with `redweb:result`, while safe
69
+ rejections use correlated protocol errors. With redweb-client use
70
+ `request(type, payload, { responseType: 'redweb:result' })` and subscribe to state
71
+ separately. This is an opt-in completion contract, not a silent change to existing
72
+ raw handlers. Custom adapters must not send from inside their callbacks.
73
+
74
+ ## Socket-bound pages (0.15.0)
75
+
3
76
  Added in Redweb 0.15.0 with redweb-client 0.3.0, installed automatically by Redweb.
4
77
  Earlier Redweb 0.14.0/client 0.2.0 packages do not provide this extension.
5
78
  Contributors editing both packages can use the optional npm-link workflow in the repository's `docs/CLIENT_DEVELOPMENT.md`.