Skip to content

Commit 4c1d6c3

Browse files
committed
docs: rename the join custom payload as metadata instead of just auth
1 parent 58f5838 commit 4c1d6c3

9 files changed

Lines changed: 30 additions & 24 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,13 @@ Requirements:
134134

135135
### Optional: SimpleServer hooks
136136

137-
`SimpleServer` accepts optional hooks for basic auth and persistence:
137+
`SimpleServer` accepts optional hooks for basic join metadata/auth handling and persistence:
138138

139139
```ts
140140
const server = new SimpleServer({
141141
port: 8787,
142142
authenticate: async (roomId, crdt, auth) => {
143-
// return 'read' | 'write' | null to deny
143+
// join metadata arrives as `auth`; return 'read' | 'write' | null to deny
144144
return "write";
145145
},
146146
onLoadDocument: async (roomId, crdt) => null, // return snapshot bytes
@@ -205,4 +205,4 @@ Node 18+ is required for local development.
205205
## FAQ
206206

207207
- How do I test locally? Use `SimpleServer` in `loro-websocket` or the Rust server.
208-
- Can I bring my own auth/storage? Yes — `SimpleServer` and the Rust server provide hooks for auth and persistence.
208+
- Can I bring my own auth/storage? Yes — `SimpleServer` and the Rust server provide hooks for join metadata/auth and persistence.

llms.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ end-to-end encrypted extension, and the full surface of the
3232

3333
| Type ID | Name | Payload Summary |
3434
| ------: | ------------------------- | ------------------------------------------------------------------------------------------------ |
35-
| `0x00` | `JoinRequest` | `varBytes auth`, `varBytes version`. |
35+
| `0x00` | `JoinRequest` | `varBytes joinPayload` (app-defined metadata, e.g., auth/session info), `varBytes version`. |
3636
| `0x01` | `JoinResponseOk` | `varString permission ("read"/"write")`, `varBytes version`, `varBytes extraMetadata`. |
3737
| `0x02` | `JoinError` | `u8 code`, `varString message`, optional `varBytes receiverVersion` when `code=version_unknown`. |
3838
| `0x03` | `DocUpdate` | `varUint N` updates followed by `N` `varBytes` chunks. |
@@ -43,12 +43,13 @@ end-to-end encrypted extension, and the full surface of the
4343

4444
### 1.2 Sync Lifecycle
4545

46-
1. Client (`Req`) sends `JoinRequest` with auth payload and local version.
46+
1. Client (`Req`) sends `JoinRequest` with a join payload (auth or other metadata) and local version.
4747
2. Server (`Recv`) responds:
4848
- `JoinResponseOk` with current version and permission, then streams
4949
backfills via `DocUpdate`/`DocUpdateFragment`.
50-
- or `JoinError` for authentication failure or unknown version. On
51-
`version_unknown`, the server includes its version for reseeding.
50+
- or `JoinError` when the join payload is rejected (e.g., auth failure) or
51+
for unknown version. On `version_unknown`, the server includes its
52+
version for reseeding.
5253
3. Clients broadcast local edits using `DocUpdate`. Payloads exceeding the
5354
size limit are sliced into fragments: send header first, then numbered
5455
fragments. Recipients reassemble by `batchId`.
@@ -237,7 +238,7 @@ adaptor.getDoc().setPeerId(1);
237238
const room = await client.join({
238239
roomId: "doc-123",
239240
crdtAdaptor: adaptor,
240-
auth?: Uint8Array, // Optional bytes forwarded to the server.
241+
auth?: Uint8Array, // Optional join metadata forwarded to the server.
241242
});
242243
```
243244

@@ -302,7 +303,7 @@ const server = new SimpleServer({
302303
port: 8787,
303304
host?: string,
304305
saveInterval?: number, // Default 60_000 ms.
305-
authenticate?: async (roomId, crdtType, auth) => "read" | "write" | null,
306+
authenticate?: async (roomId, crdtType, auth) => "read" | "write" | null, // auth is join metadata
306307
onLoadDocument?: async (roomId, crdtType) => Uint8Array | null,
307308
onSaveDocument?: async (roomId, crdtType, data) => void,
308309
});
@@ -330,7 +331,8 @@ Key behaviors:
330331
- Subscribe to `onStatusChange` to gate CRDT mutations behind `Connected`.
331332
- Use `waitForReachingServerVersion()` before assuming local state matches the
332333
server (important after reconnects).
333-
- For auth flows, encode credentials as `Uint8Array` and pass via `join({ auth })`.
334+
- For join metadata (auth tokens, roles, etc.), encode bytes as `Uint8Array`
335+
and pass via `join({ auth })`.
334336
- Remember that keepalive frames are raw text messages: handle them before
335337
attempting to decode binary protocol messages.
336338

packages/loro-protocol/README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const join = encode({
2828
type: MessageType.JoinRequest,
2929
crdt: CrdtType.Loro,
3030
roomId: "room-1",
31-
auth: new Uint8Array(),
31+
auth: new Uint8Array(), // join metadata (auth/session tokens, etc.)
3232
version: new Uint8Array(),
3333
});
3434

@@ -79,4 +79,3 @@ Notes
7979
## License
8080

8181
MIT
82-

packages/loro-protocol/src/protocol.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export interface MessageBase {
7575

7676
export interface JoinRequest extends MessageBase {
7777
type: typeof MessageType.JoinRequest;
78+
/** Application-defined join payload (auth or other metadata). */
7879
auth: Uint8Array;
7980
version: Uint8Array;
8081
}

packages/loro-websocket/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ type ClientStatusValue = typeof ClientStatus[keyof typeof ClientStatus];
9898
- `onLatency(cb): () => void` subscribes to latency updates; if a value exists, emits immediately; returns unsubscribe.
9999

100100
- Rooms
101-
- `join({ roomId, crdtAdaptor, auth? }): Promise<LoroWebsocketClientRoom>` joins a room for a given CRDT type via its adaptor. Optional `auth` is forwarded to the server’s `authenticate` hook.
101+
- `join({ roomId, crdtAdaptor, auth? }): Promise<LoroWebsocketClientRoom>` joins a room for a given CRDT type via its adaptor. Optional `auth` carries application-defined join metadata (e.g., auth/session tokens) and is forwarded to the server’s `authenticate` hook.
102102
- Room API: `leave(): Promise<void>`, `waitForReachingServerVersion(): Promise<void>`, `destroy(): Promise<void>`.
103103

104104
## Status & Reconnect Model
@@ -127,11 +127,11 @@ type ClientStatusValue = typeof ClientStatus[keyof typeof ClientStatus];
127127
## Rooms & Rejoin
128128

129129
- Join handshake
130-
- `join()` sends a `JoinRequest` with the adaptor’s CRDT type, version, and optional auth.
130+
- `join()` sends a `JoinRequest` with the adaptor’s CRDT type, version, and optional join metadata (`auth` bytes).
131131
- On `JoinResponseOk`, the adaptor reconciles to the server’s version and begins streaming updates.
132132

133133
- Rejoin after reconnect
134-
- The client tracks active rooms and their auth. After reconnect, it re‑sends `JoinRequest` for each active room and the adaptor re‑syncs.
134+
- The client tracks active rooms and their join metadata. After reconnect, it re‑sends `JoinRequest` for each active room and the adaptor re‑syncs.
135135
- If the server responds `VersionUnknown`, the client retries using `adaptor.getAlternativeVersion()` or an empty version as a fallback.
136136
- For `%ELO`, updates that arrive right after join may be buffered briefly to cover backfills that race the join.
137137

@@ -148,7 +148,7 @@ import { SimpleServer } from "loro-websocket/server";
148148
const server = new SimpleServer({
149149
port: 8787,
150150
authenticate: async (_roomId, _crdt, auth) => {
151-
// return "read" | "write" | null
151+
// join metadata is passed as `auth`; return "read" | "write" | null
152152
return new TextDecoder().decode(auth) === "readonly" ? "read" : "write";
153153
},
154154
onLoadDocument: async (_roomId, _crdt) => null,
@@ -183,15 +183,15 @@ console.log("last RTT:", client.getLatency());
183183
off();
184184
```
185185

186-
- Join with auth
186+
- Join with join metadata/auth
187187

188188
```ts
189189
const adaptor = new LoroAdaptor();
190190
adaptor.getDoc().setPeerId(42);
191191
await client.join({
192192
roomId: "project-123",
193193
crdtAdaptor: adaptor,
194-
auth: new TextEncoder().encode("write-token"),
194+
auth: new TextEncoder().encode("write-token"), // application-defined join payload
195195
});
196196
```
197197

packages/loro-websocket/src/client/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,9 @@ export class LoroWebsocketClient {
770770
});
771771
}
772772

773+
/**
774+
* Join a room; `auth` carries application-defined join metadata forwarded to the server.
775+
*/
773776
join({
774777
roomId,
775778
crdtAdaptor,

packages/loro-websocket/src/server/simple-server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export interface SimpleServerConfig {
4040
crdtType: CrdtType,
4141
data: Uint8Array
4242
) => Promise<void>;
43+
/** Map join payload (`auth`) to permission; return null to reject. */
4344
authenticate?: (
4445
roomId: string,
4546
crdtType: CrdtType,

protocol-e2ee.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ Rationale: An explicit random IV per record eliminates IV‑reuse risk and simpl
104104

105105
Req and Recv follow the same join/sync rules as `%LOR`:
106106

107-
- JoinRequest carries authentication and a document version (opaque to the protocol). Recv may respond with JoinResponseOk, JoinError, and may push missing updates.
107+
- JoinRequest carries application-defined join metadata (often auth) and a document version (both opaque to the protocol). Recv may respond with JoinResponseOk, JoinError, and may push missing updates.
108108
- When sending updates, Req packs one or more `%ELO` records into a `DocUpdate` payload. If large, use fragments per the base protocol.
109109
- Recv broadcasts received updates to other subscribers in the same room.
110110
- Leave unsubscribes from the room.

protocol.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ Note: Keepalive frames are special and bypass this envelope entirely. When the e
4949
## Message Types
5050

5151
- 0x00: JoinRequest.
52-
- `varBytes` authentication payload for the target room.
52+
- `varBytes` join payload (application-defined metadata such as auth/session info).
5353
- `varBytes` for the requester's document version.
5454
- 0x01: JoinResponseOk.
5555
- `varString` permission: "read" | "write".
@@ -80,9 +80,9 @@ Note: Keepalive frames are special and bypass this envelope entirely. When the e
8080

8181
Req sends a `JoinRequest` to Recv.
8282

83-
- If authentication fails, Recv sends `JoinError(code=0x02 auth_failed)`.
84-
- If authentication succeeds but the version is unknown, Recv sends `JoinError(code=0x01 version_unknown)` and includes its version.
85-
- If authentication succeeds, Recv sends `JoinResponseOk` with its latest known version of the document. Recv may then send the updates missing from Req through `DocUpdate` or `DocUpdateFragment` messages.
83+
- If Recv rejects the join payload (e.g., authentication/authorization fails), it sends `JoinError(code=0x02 auth_failed)`.
84+
- If the join payload is accepted but the version is unknown, Recv sends `JoinError(code=0x01 version_unknown)` and includes its version.
85+
- If the join payload is accepted, Recv sends `JoinResponseOk` with its latest known version of the document. Recv may then send the updates missing from Req through `DocUpdate` or `DocUpdateFragment` messages.
8686

8787
When Recv receives updates in the same room from other peers, it broadcasts them to all the other peers through `DocUpdate` or `DocUpdateFragment` messages.
8888

@@ -118,7 +118,7 @@ Codes:
118118

119119
- 0x00 unknown: unspecified error.
120120
- 0x01 version_unknown: cannot interpret provided version. Extra: `receiver_version`.
121-
- 0x02 auth_failed: authentication/authorization failed.
121+
- 0x02 auth_failed: authentication/authorization failed or the join payload was rejected.
122122
- 0x7F app_error: Extra `varString app_code` (free-form, e.g., `quota_exceeded`).
123123

124124
### UpdateError (0x06)

0 commit comments

Comments
 (0)