1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
|
# JCHAT - JMAP-based Chat Protocol and Implementation
JCHAT is a chat protocol built on top of JMAP (JSON Meta Application Protocol) [RFC8620], providing real-time messaging capabilities with efficient synchronization and push notifications.
## Project Structure
```
jchat/
├── draft-jchat-00.txt # RFC draft specification
├── rfc8620.txt # Base JMAP RFC for reference
├── server/ # Erlang/OTP server implementation
│ ├── src/ # Server source code
│ ├── test/ # Comprehensive test suite
│ ├── config/ # Configuration files
│ ├── rebar.config # Build configuration
│ └── Makefile # Build automation
└── client/ # HTML/JavaScript web client
├── index.html # Main client interface
├── jmap-client.js # JMAP client library
├── app.js # Application logic
└── package.json # Project metadata
```
## Features
### Protocol Features (JCHAT RFC)
- **Conversations**: Group messaging with metadata and participant management
- **Messages**: Rich text messages with attachments, replies, and reactions
- **Participants**: User roles, permissions, and presence management
- **Real-time Updates**: Push notifications and efficient delta synchronization
- **Standards Compliant**: Built on proven JMAP foundation
### Server Implementation
- **Erlang/OTP**: Fault-tolerant, concurrent server architecture
- **Mnesia Database**: Built-in distributed database for persistence
- **HTTP API**: RESTful JMAP endpoints with JSON serialization
- **Push Notifications**: Server-Sent Events for real-time updates
- **Comprehensive Testing**: Unit, property-based, and performance tests
### Web Client
- **Modern UI**: Responsive design with conversation list and chat interface
- **Real-time Messaging**: Live message updates and typing indicators
- **Cross-platform**: Works in any modern web browser
- **JMAP Integration**: Native support for JMAP protocol features
## Quick Start
### Prerequisites
- Erlang/OTP 24+ (for server)
- Any HTTP server for client (shttpd, Python, nginx, etc.)
- rebar3 (Erlang build tool)
### Running the Server
```bash
cd server
make compile
make run
```
The server will start on http://localhost:8080 with the following endpoints:
- `GET /jmap/session` - JMAP session information
- `POST /jmap/api` - JMAP method calls
- `GET /jmap/eventsource` - Server-Sent Events for push notifications
### Running the Client
The client is a dependency-free web application built with vanilla HTML, CSS, and JavaScript.
#### Quick Start (no installation required)
Using shttpd (recommended):
```bash
cd client
shttpd . --port 3000
```
Using Python:
```bash
cd client
python3 -m http.server 3000
```
Using any web server:
```bash
cd client
# Point nginx, Apache, or any HTTP server to this directory
```
The client will be available at http://localhost:3000
## Testing
### Server Tests
```bash
cd server
make test # Run all tests
make test-unit # Unit tests only
make test-prop # Property-based tests
make test-perf # Performance tests
```
### Manual Testing
1. Start the server: `cd server && make run`
2. Start the client: `cd client && shttpd . --port 3000`
3. Open http://localhost:3000 in your browser
4. The client will automatically connect to the server
## API Examples
### Create a Conversation
```javascript
const conversation = await jmapClient.createConversation({
title: "Project Discussion",
participantIds: ["user1", "user2", "user3"]
});
```
### Send a Message
```javascript
const message = await jmapClient.sendMessage(
conversationId,
"Hello, everyone!",
"text/plain"
);
```
### Query Messages
```javascript
const messages = await jmapClient.queryMessages({
inConversation: conversationId,
after: "2025-08-15T10:00:00Z"
});
```
## Architecture
### JMAP Foundation
JCHAT extends JMAP with chat-specific object types:
- **Conversation**: Container for messages and participants
- **Message**: Individual chat messages with rich metadata
- **Participant**: User membership in conversations
- **Presence**: User availability and status information
### Server Architecture
```
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ HTTP Layer │────│ JMAP Methods │────│ Data Layer │
│ (Cowboy) │ │ (Conversations, │ │ (Mnesia) │
│ │ │ Messages, etc) │ │ │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │ │
│ ┌────────────────┐ │
└──────────────│ Push Manager │───────────────┘
│ (Server-Sent │
│ Events) │
└────────────────┘
```
### Client Architecture
```
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ UI Layer │────│ Application │────│ JMAP Client │
│ (HTML/CSS) │ │ Logic │ │ Library │
│ │ │ (JChatApp) │ │ (JMAPClient) │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │
│ ┌────────────────┐
└──────────────│ Server API │
│ (HTTP/JSON) │
└────────────────┘
```
## Protocol Details
### JMAP Capability
```
"urn:ietf:params:jmap:chat"
```
### Core Methods
- `Conversation/get`, `Conversation/set`, `Conversation/query`, `Conversation/changes`
- `Message/get`, `Message/set`, `Message/query`, `Message/changes`
- `Participant/get`, `Participant/set`, `Participant/changes`
- `Presence/get`, `Presence/set`
### Example JMAP Request
```json
{
"using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:chat"],
"methodCalls": [
["Conversation/query", {
"accountId": "primary",
"sort": [{"property": "lastMessageAt", "isAscending": false}]
}, "c1"],
["Message/query", {
"accountId": "primary",
"filter": {"inConversation": "#c1/ids/0"},
"sort": [{"property": "sentAt", "isAscending": true}]
}, "c2"]
]
}
```
## Development
### Server Development
- Add new JMAP methods in `src/jchat_methods.erl`
- Extend data models in `src/jchat.hrl`
- Database operations in `src/jchat_db.erl`
- Add tests in `test/` directory
### Client Development
- UI components in `index.html` and CSS
- JMAP protocol handling in `jmap-client.js`
- Application logic in `app.js`
- Build with any modern JavaScript toolchain
### Testing Strategy
1. **Unit Tests**: Individual function testing
2. **Integration Tests**: Full JMAP request/response cycles
3. **Property Tests**: Randomized testing with PropEr
4. **Performance Tests**: Load testing and benchmarks
5. **Manual Tests**: End-to-end user scenarios
## Deployment
### Production Server
```bash
cd server
make release
_build/prod/rel/jchat/bin/jchat start
```
### Docker Deployment
```bash
# Build server image
cd server
docker build -t jchat-server .
# Build client image
cd client
docker build -t jchat-client .
# Run with docker-compose
docker-compose up
```
## Contributing
1. Read the JCHAT RFC draft (`draft-jchat-00.txt`)
2. Follow Erlang/OTP conventions for server code
3. Use modern JavaScript practices for client code
4. Add tests for all new features
5. Update documentation as needed
## Standards Compliance
- **RFC 8620**: JSON Meta Application Protocol (JMAP)
- **RFC 8259**: JSON Data Interchange Format
- **RFC 3339**: Date and Time on the Internet
- **RFC 7231**: HTTP/1.1 Semantics and Content
## License
This project is licensed under the MIT License - see the LICENSE file for details.
## References
- [RFC 8620 - JMAP](https://tools.ietf.org/html/rfc8620)
- [JMAP Specifications](https://jmap.io/spec.html)
- [Erlang/OTP Documentation](https://erlang.org/doc/)
- [Modern Web Standards](https://developer.mozilla.org/)
|