Skip to content

Commit 8099747

Browse files
eitsupirandy3k
authored andcommitted
docs(sess): restore protocol detail in README
1 parent 35620ea commit 8099747

1 file changed

Lines changed: 181 additions & 29 deletions

File tree

‎sess/README.md‎

Lines changed: 181 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
# `sess`: Modern R IPC Protocol
22

3-
The `sess` package provides a lightweight IPC layer between an R session and a client (such as the VS Code R extension). It uses JSON-RPC 2.0 messages over:
3+
The `sess` package provides an IPC layer between an R session and a client (such as the VS Code R extension).
4+
5+
Transport:
46

57
- Unix domain sockets (macOS/Linux)
68
- Windows named pipes
79

10+
Protocol:
11+
12+
- JSON-RPC 2.0 messages
13+
- JSON Lines (JSONL, newline-delimited JSON) framing (one JSON message per line)
14+
815
## 1. Connection Handshake
916

1017
Start the client connection from R:
@@ -22,20 +29,86 @@ If `pipe_path` is omitted, `connect()` resolves it in this order:
2229
1. `SESS_PIPE` environment variable
2330
2. `~/.vscode-R/sessions/{PID}.json` (`pipe` field)
2431

25-
After connecting, `sess` sends an `attach` notification with R version, process id, and session metadata.
32+
After connecting, `sess` sends an `attach` notification.
33+
34+
Example:
35+
36+
```json
37+
{
38+
"jsonrpc": "2.0",
39+
"method": "attach",
40+
"params": {
41+
"version": "4.5.0",
42+
"pid": 12345,
43+
"tempdir": "/tmp/Rtmp.../sess",
44+
"wd": "/path/to/project",
45+
"info": {
46+
"command": "/usr/bin/R",
47+
"version": "R version 4.5.0 (...) ",
48+
"start_time": "2026-05-05 06:00:00"
49+
}
50+
}
51+
}
52+
```
53+
54+
## 2. Message Transport and Framing
55+
56+
Transport uses JSON Lines (JSONL, newline-delimited JSON):
2657

27-
## 2. Message Transport
58+
- sender writes one JSON-RPC object + `\n`
59+
- receiver buffers stream chunks and dispatches complete lines only
2860

29-
Transport is NDJSON (newline-delimited JSON). Each line is one JSON-RPC message.
61+
This preserves JSON-RPC semantics while handling stream fragmentation safely.
3062

31-
- R writes JSON-RPC payloads with a trailing `\n`
32-
- R polls the pipe periodically and dispatches complete lines
63+
## 3. JSON-RPC Message Types
3364

34-
The protocol semantics remain JSON-RPC 2.0.
65+
### Notification (one-way)
3566

36-
### Notifications (`notify_client`)
67+
```json
68+
{
69+
"jsonrpc": "2.0",
70+
"method": "method_name",
71+
"params": {}
72+
}
73+
```
74+
75+
### Request (expects response)
76+
77+
```json
78+
{
79+
"jsonrpc": "2.0",
80+
"id": 1,
81+
"method": "method_name",
82+
"params": {}
83+
}
84+
```
85+
86+
### Response (success)
3787

38-
R sends JSON-RPC notifications (without `id`) for one-way events such as:
88+
```json
89+
{
90+
"jsonrpc": "2.0",
91+
"id": 1,
92+
"result": {}
93+
}
94+
```
95+
96+
### Response (error)
97+
98+
```json
99+
{
100+
"jsonrpc": "2.0",
101+
"id": 1,
102+
"error": {
103+
"code": -32601,
104+
"message": "Method not found"
105+
}
106+
}
107+
```
108+
109+
## 4. Notifications from R to Client
110+
111+
`notify_client()` sends one-way events (no `id`), including:
39112

40113
- `attach`
41114
- `dataview`
@@ -47,10 +120,11 @@ R sends JSON-RPC notifications (without `id`) for one-way events such as:
47120
- `restart_r`
48121
- `send_to_console`
49122

50-
### Requests (`request_client`)
123+
## 5. Requests from R to Client (`request_client`)
124+
125+
`request_client()` sends JSON-RPC requests and waits for matching response `id`.
51126

52-
R can synchronously call client methods (JSON-RPC request with `id`) via `request_client()`.
53-
This is used for RStudio API emulation methods, such as:
127+
Used by RStudio API emulation methods, such as:
54128

55129
- `rstudioapi/active_editor_context`
56130
- `rstudioapi/replace_text_in_current_selection`
@@ -65,16 +139,89 @@ This is used for RStudio API emulation methods, such as:
65139
- `rstudioapi/document_new`
66140
- `rstudioapi/document_close`
67141

68-
### Client Pull Requests
142+
Coordinate convention on the wire:
143+
144+
- rows/columns are 1-indexed (R-style)
145+
- client may convert to internal 0-indexed representation
146+
147+
## 6. Requests from Client to R (Pull API)
148+
149+
Client queries R state through JSON-RPC requests.
150+
151+
### `workspace`
152+
153+
Request:
154+
155+
```json
156+
{"jsonrpc":"2.0","id":1,"method":"workspace","params":{}}
157+
```
158+
159+
Response (example):
160+
161+
```json
162+
{
163+
"jsonrpc": "2.0",
164+
"id": 1,
165+
"result": {
166+
"globalenv": {
167+
"my_df": {"class": ["data.frame"], "type": "list", "length": 11}
168+
},
169+
"search": ["package:stats", "package:graphics"],
170+
"loaded_namespaces": ["sess", "utils"]
171+
}
172+
}
173+
```
174+
175+
### `plot_latest`
176+
177+
Request params example:
178+
179+
```json
180+
{"width":800,"height":600,"format":"svglite"}
181+
```
182+
183+
Response example:
184+
185+
```json
186+
{"jsonrpc":"2.0","id":2,"result":{"format":"svglite","data":"<base64 or svg payload>"}}
187+
```
188+
189+
### `hover`
69190

70-
The client can request state from R with JSON-RPC requests:
191+
Request params example:
71192

72-
- `workspace`
73-
- `plot_latest`
74-
- `hover`
75-
- `completion`
193+
```json
194+
{"expr":"head(mtcars)"}
195+
```
76196

77-
## 3. Hook Registration & Options
197+
Response example:
198+
199+
```json
200+
{"jsonrpc":"2.0","id":3,"result":{"str":"'data.frame': 6 obs. ..."}}
201+
```
202+
203+
### `completion`
204+
205+
Request params example:
206+
207+
```json
208+
{"expr":"mtcars","trigger":"$"}
209+
```
210+
211+
Response example:
212+
213+
```json
214+
{
215+
"jsonrpc": "2.0",
216+
"id": 4,
217+
"result": [
218+
{"name":"mpg","type":"double","str":"numeric"},
219+
{"name":"cyl","type":"double","str":"numeric"}
220+
]
221+
}
222+
```
223+
224+
## 7. Hook Registration and Options
78225

79226
`connect()` initializes runtime hooks via `register_hooks()`.
80227

@@ -84,27 +231,32 @@ Intercepted features include:
84231
- `browser()`, `viewer()`, `page_viewer()`
85232
- help topic rendering hooks
86233

87-
Relevant options include:
234+
Relevant options:
88235

89236
- `sess.row_limit`
90237
- `sess.dataview`
91238
- `sess.browser`
92239
- `sess.webview`
93240
- `sess.helpPanel`
94241

95-
## 4. Connection Discovery
242+
## 8. Discovery File
96243

97-
To support VS Code reloads and attach workflows, the extension writes:
244+
To support reloads and attach workflows, the extension writes:
98245

99246
- `~/.vscode-R/sessions/{PID}.json`
100247

101-
`sess::connect()` reads this file as a fallback when direct connection parameters are not provided.
248+
`sess::connect()` reads this file as fallback when direct pipe parameters are unavailable.
249+
250+
## 9. What Changed from the WebSocket Transport
251+
252+
Changed:
102253

103-
## 5. Legacy IPC Comparison
254+
- transport is now UDS / named pipe
255+
- framing is JSON Lines (JSONL) over stream sockets
256+
- authentication token exchange is removed
104257

105-
Compared with legacy file-watcher IPC, `sess` provides:
258+
Unchanged:
106259

107-
- JSON-RPC 2.0 for structured messaging
108-
- socket/pipe transport instead of lock-file command channels
109-
- on-demand workspace queries
110-
- lower background churn and fewer file watch races
260+
- JSON-RPC method names and payload shapes
261+
- request/response correlation by `id`
262+
- high-level feature behavior (workspace, hover, completion, plot, dataview, RStudio API emulation)

0 commit comments

Comments
 (0)