@xtr-dev/rondevu-server 0.0.1

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/DEPLOYMENT.md ADDED
@@ -0,0 +1,346 @@
1
+ # Deployment Guide
2
+
3
+ This guide covers deploying Rondevu to various platforms.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Cloudflare Workers](#cloudflare-workers)
8
+ - [Docker](#docker)
9
+ - [Node.js](#nodejs)
10
+
11
+ ---
12
+
13
+ ## Cloudflare Workers
14
+
15
+ Deploy to Cloudflare's edge network using Cloudflare Workers and KV storage.
16
+
17
+ ### Prerequisites
18
+
19
+ ```bash
20
+ npm install -g wrangler
21
+ ```
22
+
23
+ ### Setup
24
+
25
+ 1. **Login to Cloudflare**
26
+ ```bash
27
+ wrangler login
28
+ ```
29
+
30
+ 2. **Create KV Namespace**
31
+ ```bash
32
+ # For production
33
+ wrangler kv:namespace create SESSIONS
34
+
35
+ # This will output something like:
36
+ # { binding = "SESSIONS", id = "abc123..." }
37
+ ```
38
+
39
+ 3. **Update wrangler.toml**
40
+
41
+ Edit `wrangler.toml` and replace `YOUR_KV_NAMESPACE_ID` with the ID from step 2:
42
+
43
+ ```toml
44
+ [[kv_namespaces]]
45
+ binding = "SESSIONS"
46
+ id = "abc123..." # Your actual KV namespace ID
47
+ ```
48
+
49
+ 4. **Configure Environment Variables** (Optional)
50
+
51
+ Update `wrangler.toml` to customize settings:
52
+
53
+ ```toml
54
+ [vars]
55
+ SESSION_TIMEOUT = "300000" # Session timeout in milliseconds
56
+ CORS_ORIGINS = "https://example.com,https://app.example.com"
57
+ ```
58
+
59
+ ### Local Development
60
+
61
+ ```bash
62
+ # Run locally with Wrangler
63
+ npx wrangler dev
64
+
65
+ # The local development server will:
66
+ # - Start on http://localhost:8787
67
+ # - Use a local KV namespace automatically
68
+ # - Hot-reload on file changes
69
+ ```
70
+
71
+ ### Production Deployment
72
+
73
+ ```bash
74
+ # Deploy to Cloudflare Workers
75
+ npx wrangler deploy
76
+
77
+ # This will output your worker URL:
78
+ # https://rondevu.YOUR_SUBDOMAIN.workers.dev
79
+ ```
80
+
81
+ ### Custom Domain (Optional)
82
+
83
+ 1. Go to your Cloudflare Workers dashboard
84
+ 2. Select your worker
85
+ 3. Click "Triggers" → "Add Custom Domain"
86
+ 4. Enter your domain (e.g., `api.example.com`)
87
+
88
+ ### Monitoring
89
+
90
+ View logs and analytics:
91
+
92
+ ```bash
93
+ # Stream real-time logs
94
+ npx wrangler tail
95
+
96
+ # View in dashboard
97
+ # Visit: https://dash.cloudflare.com → Workers & Pages
98
+ ```
99
+
100
+ ### Environment Variables
101
+
102
+ | Variable | Default | Description |
103
+ |----------|---------|-------------|
104
+ | `SESSION_TIMEOUT` | `300000` | Session timeout in milliseconds |
105
+ | `CORS_ORIGINS` | `*` | Comma-separated allowed origins |
106
+
107
+ ### Pricing
108
+
109
+ Cloudflare Workers Free Tier includes:
110
+ - 100,000 requests/day
111
+ - 10ms CPU time per request
112
+ - KV: 100,000 reads/day, 1,000 writes/day
113
+
114
+ For higher usage, see [Cloudflare Workers pricing](https://workers.cloudflare.com/#plans).
115
+
116
+ ### Advantages
117
+
118
+ - **Global Edge Network**: Deploy to 300+ locations worldwide
119
+ - **Instant Scaling**: Handles traffic spikes automatically
120
+ - **Low Latency**: Runs close to your users
121
+ - **No Server Management**: Fully serverless
122
+ - **Free Tier**: Generous limits for small projects
123
+
124
+ ---
125
+
126
+ ## Docker
127
+
128
+ ### Quick Start
129
+
130
+ ```bash
131
+ # Build
132
+ docker build -t rondevu .
133
+
134
+ # Run with in-memory SQLite
135
+ docker run -p 3000:3000 -e STORAGE_PATH=:memory: rondevu
136
+
137
+ # Run with persistent SQLite
138
+ docker run -p 3000:3000 \
139
+ -v $(pwd)/data:/app/data \
140
+ -e STORAGE_PATH=/app/data/sessions.db \
141
+ rondevu
142
+ ```
143
+
144
+ ### Docker Compose
145
+
146
+ Create a `docker-compose.yml`:
147
+
148
+ ```yaml
149
+ version: '3.8'
150
+
151
+ services:
152
+ rondevu:
153
+ build: .
154
+ ports:
155
+ - "3000:3000"
156
+ environment:
157
+ - PORT=3000
158
+ - STORAGE_TYPE=sqlite
159
+ - STORAGE_PATH=/app/data/sessions.db
160
+ - SESSION_TIMEOUT=300000
161
+ - CORS_ORIGINS=*
162
+ volumes:
163
+ - ./data:/app/data
164
+ restart: unless-stopped
165
+ ```
166
+
167
+ Run with:
168
+ ```bash
169
+ docker-compose up -d
170
+ ```
171
+
172
+ ### Environment Variables
173
+
174
+ | Variable | Default | Description |
175
+ |----------|---------|-------------|
176
+ | `PORT` | `3000` | Server port |
177
+ | `STORAGE_TYPE` | `sqlite` | Storage backend |
178
+ | `STORAGE_PATH` | `/app/data/sessions.db` | SQLite database path |
179
+ | `SESSION_TIMEOUT` | `300000` | Session timeout in ms |
180
+ | `CORS_ORIGINS` | `*` | Allowed CORS origins |
181
+
182
+ ---
183
+
184
+ ## Node.js
185
+
186
+ ### Production Deployment
187
+
188
+ 1. **Install Dependencies**
189
+ ```bash
190
+ npm ci --production
191
+ ```
192
+
193
+ 2. **Build TypeScript**
194
+ ```bash
195
+ npm run build
196
+ ```
197
+
198
+ 3. **Set Environment Variables**
199
+ ```bash
200
+ export PORT=3000
201
+ export STORAGE_TYPE=sqlite
202
+ export STORAGE_PATH=./data/sessions.db
203
+ export SESSION_TIMEOUT=300000
204
+ export CORS_ORIGINS=*
205
+ ```
206
+
207
+ 4. **Run**
208
+ ```bash
209
+ npm start
210
+ ```
211
+
212
+ ### Process Manager (PM2)
213
+
214
+ For production, use a process manager like PM2:
215
+
216
+ 1. **Install PM2**
217
+ ```bash
218
+ npm install -g pm2
219
+ ```
220
+
221
+ 2. **Create ecosystem.config.js**
222
+ ```javascript
223
+ module.exports = {
224
+ apps: [{
225
+ name: 'rondevu',
226
+ script: './dist/index.js',
227
+ instances: 'max',
228
+ exec_mode: 'cluster',
229
+ env: {
230
+ NODE_ENV: 'production',
231
+ PORT: 3000,
232
+ STORAGE_TYPE: 'sqlite',
233
+ STORAGE_PATH: './data/sessions.db',
234
+ SESSION_TIMEOUT: 300000,
235
+ CORS_ORIGINS: '*'
236
+ }
237
+ }]
238
+ };
239
+ ```
240
+
241
+ 3. **Start with PM2**
242
+ ```bash
243
+ pm2 start ecosystem.config.js
244
+ pm2 save
245
+ pm2 startup
246
+ ```
247
+
248
+ ### Systemd Service
249
+
250
+ Create `/etc/systemd/system/rondevu.service`:
251
+
252
+ ```ini
253
+ [Unit]
254
+ Description=Rondevu Peer Discovery and Signaling Server
255
+ After=network.target
256
+
257
+ [Service]
258
+ Type=simple
259
+ User=www-data
260
+ WorkingDirectory=/opt/rondevu
261
+ ExecStart=/usr/bin/node dist/index.js
262
+ Restart=on-failure
263
+ Environment=PORT=3000
264
+ Environment=STORAGE_TYPE=sqlite
265
+ Environment=STORAGE_PATH=/opt/rondevu/data/sessions.db
266
+ Environment=SESSION_TIMEOUT=300000
267
+ Environment=CORS_ORIGINS=*
268
+
269
+ [Install]
270
+ WantedBy=multi-user.target
271
+ ```
272
+
273
+ Enable and start:
274
+ ```bash
275
+ sudo systemctl enable rondevu
276
+ sudo systemctl start rondevu
277
+ sudo systemctl status rondevu
278
+ ```
279
+
280
+ ---
281
+
282
+ ## Troubleshooting
283
+
284
+ ### Docker
285
+
286
+ **Issue: Permission denied on /app/data**
287
+ - Ensure volume permissions are correct
288
+ - The container runs as user `node` (UID 1000)
289
+
290
+ **Issue: Database locked**
291
+ - Don't share the same SQLite database file across multiple containers
292
+ - Use one instance or implement a different storage backend
293
+
294
+ ### Node.js
295
+
296
+ **Issue: EADDRINUSE**
297
+ - Port is already in use, change `PORT` environment variable
298
+
299
+ **Issue: Database is locked**
300
+ - Another process is using the database
301
+ - Ensure only one instance is running with the same database file
302
+
303
+ ---
304
+
305
+ ## Performance Tuning
306
+
307
+ ### Node.js/Docker
308
+
309
+ - Set `SESSION_TIMEOUT` appropriately to balance resource usage
310
+ - For high traffic, use `STORAGE_PATH=:memory:` with session replication
311
+ - Consider horizontal scaling with a shared database backend
312
+
313
+ ---
314
+
315
+ ## Security Considerations
316
+
317
+ 1. **HTTPS**: Always use HTTPS in production
318
+ - Use a reverse proxy (nginx, Caddy) for Node.js deployments
319
+ - Docker deployments should be behind a reverse proxy
320
+
321
+ 2. **Rate Limiting**: Implement rate limiting at the proxy level
322
+
323
+ 3. **CORS**: Configure CORS origins appropriately
324
+ - Don't use `*` in production
325
+ - Set specific allowed origins: `https://example.com,https://app.example.com`
326
+
327
+ 4. **Input Validation**: SDP offers/answers are stored as-is; validate on client side
328
+
329
+ 5. **Session Codes**: UUID v4 codes provide strong entropy (2^122 combinations)
330
+
331
+ 6. **Origin Isolation**: Sessions are isolated by Origin header to organize topics by domain
332
+
333
+ ---
334
+
335
+ ## Scaling
336
+
337
+ ### Horizontal Scaling
338
+
339
+ - **Docker/Node.js**: Use a shared database (not SQLite) for multiple instances
340
+ - Implement a Redis or PostgreSQL storage adapter
341
+
342
+ ### Vertical Scaling
343
+
344
+ - Increase `SESSION_TIMEOUT` or cleanup frequency as needed
345
+ - Monitor database size and connection pool
346
+ - For Node.js, monitor memory usage and increase if needed
package/Dockerfile ADDED
@@ -0,0 +1,57 @@
1
+ # Build stage
2
+ FROM node:20-alpine AS builder
3
+
4
+ WORKDIR /app
5
+
6
+ # Copy package files
7
+ COPY package*.json ./
8
+
9
+ # Install dependencies
10
+ RUN npm ci
11
+
12
+ # Copy source files
13
+ COPY tsconfig.json ./
14
+ COPY build.js ./
15
+ COPY src ./src
16
+
17
+ # Build TypeScript
18
+ RUN npm run build
19
+
20
+ # Production stage
21
+ FROM node:20-alpine
22
+
23
+ WORKDIR /app
24
+
25
+ # Install production dependencies only
26
+ COPY package*.json ./
27
+ RUN npm ci --omit=dev && \
28
+ npm cache clean --force
29
+
30
+ # Copy built files from builder
31
+ COPY --from=builder /app/dist ./dist
32
+
33
+ # Create data directory for SQLite
34
+ RUN mkdir -p /app/data && \
35
+ chown -R node:node /app
36
+
37
+ # Switch to non-root user
38
+ USER node
39
+
40
+ # Environment variables with defaults
41
+ ENV PORT=3000
42
+ ENV STORAGE_TYPE=sqlite
43
+ ENV STORAGE_PATH=/app/data/sessions.db
44
+ ENV SESSION_TIMEOUT=300000
45
+ ENV CODE_CHARS=0123456789
46
+ ENV CODE_LENGTH=9
47
+ ENV CORS_ORIGINS=*
48
+
49
+ # Expose port
50
+ EXPOSE 3000
51
+
52
+ # Health check
53
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
54
+ CMD node -e "require('http').get('http://localhost:${PORT}/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"
55
+
56
+ # Start server
57
+ CMD ["node", "dist/index.js"]
package/README.md ADDED
@@ -0,0 +1,242 @@
1
+ # Rondevu
2
+
3
+ An open signaling and tracking server for peer discovery. Enables peers to find each other through a topic-based HTTP API with Origin isolation for organizing peer-to-peer applications.
4
+
5
+ ## Features
6
+
7
+ - 🚀 **Fast & Lightweight** - Built with [Hono](https://hono.dev/) framework
8
+ - 📂 **Topic-Based Organization** - Group sessions by topic for easy peer discovery
9
+ - 🔒 **Origin Isolation** - Sessions are isolated by HTTP Origin header to group topics by domain
10
+ - 🏷️ **Peer Identification** - Info field prevents duplicate connections to same peer
11
+ - 🔌 **Pluggable Storage** - Storage interface supports SQLite and in-memory adapters
12
+ - 🐳 **Docker Ready** - Minimal Alpine-based Docker image
13
+ - ⏱️ **Session Timeout** - Configurable session expiration from initiation time
14
+ - 🔐 **Type Safe** - Written in TypeScript with full type definitions
15
+
16
+ ## Quick Start
17
+
18
+ ### Using Node.js
19
+
20
+ ```bash
21
+ # Install dependencies
22
+ npm install
23
+
24
+ # Run in development mode
25
+ npm run dev
26
+
27
+ # Build and run in production
28
+ npm run build
29
+ npm start
30
+ ```
31
+
32
+ ### Using Docker
33
+
34
+ ```bash
35
+ # Build the image
36
+ docker build -t rondevu .
37
+
38
+ # Run with default settings (SQLite database)
39
+ docker run -p 3000:3000 rondevu
40
+
41
+ # Run with in-memory storage
42
+ docker run -p 3000:3000 -e STORAGE_TYPE=memory rondevu
43
+
44
+ # Run with custom timeout (10 minutes)
45
+ docker run -p 3000:3000 -e SESSION_TIMEOUT=600000 rondevu
46
+ ```
47
+
48
+ ### Using Cloudflare Workers
49
+
50
+ ```bash
51
+ # Install Wrangler CLI
52
+ npm install -g wrangler
53
+
54
+ # Login to Cloudflare
55
+ wrangler login
56
+
57
+ # Create KV namespace
58
+ wrangler kv:namespace create SESSIONS
59
+
60
+ # Update wrangler.toml with the KV namespace ID
61
+
62
+ # Deploy to Cloudflare's edge network
63
+ npx wrangler deploy
64
+ ```
65
+
66
+ See [DEPLOYMENT.md](./DEPLOYMENT.md#cloudflare-workers) for detailed instructions.
67
+
68
+ ## Configuration
69
+
70
+ Configuration is done through environment variables:
71
+
72
+ | Variable | Description | Default |
73
+ |--------------------|--------------------------------------------------|-------------|
74
+ | `PORT` | Server port | `3000` |
75
+ | `STORAGE_TYPE` | Storage backend: `sqlite` or `memory` | `sqlite` |
76
+ | `STORAGE_PATH` | Path to SQLite database file | `./data.db` |
77
+ | `SESSION_TIMEOUT` | Session timeout in milliseconds | `300000` |
78
+ | `CORS_ORIGINS` | Comma-separated list of allowed origins | `*` |
79
+
80
+ ### Example .env file
81
+
82
+ ```env
83
+ PORT=3000
84
+ STORAGE_TYPE=sqlite
85
+ STORAGE_PATH=./sessions.db
86
+ SESSION_TIMEOUT=300000
87
+ CORS_ORIGINS=https://example.com,https://app.example.com
88
+ ```
89
+
90
+ ## API Documentation
91
+
92
+ See [API.md](./API.md) for complete API documentation.
93
+
94
+ ### Quick Overview
95
+
96
+ **List all active topics (with pagination):**
97
+ ```bash
98
+ curl -X GET http://localhost:3000/ \
99
+ -H "Origin: https://example.com"
100
+ # Returns: {"topics":[{"topic":"my-room","count":3}],"pagination":{...}}
101
+ ```
102
+
103
+ **Create an offer (announce yourself as available):**
104
+ ```bash
105
+ curl -X POST http://localhost:3000/my-room/offer \
106
+ -H "Content-Type: application/json" \
107
+ -H "Origin: https://example.com" \
108
+ -d '{"info":"peer-123","offer":"<SIGNALING_DATA>"}'
109
+ # Returns: {"code":"550e8400-e29b-41d4-a716-446655440000"}
110
+ ```
111
+
112
+ **List available peers in a topic:**
113
+ ```bash
114
+ curl -X GET http://localhost:3000/my-room/sessions \
115
+ -H "Origin: https://example.com"
116
+ # Returns: {"sessions":[...]}
117
+ ```
118
+
119
+ **Connect to a peer:**
120
+ ```bash
121
+ curl -X POST http://localhost:3000/answer \
122
+ -H "Content-Type: application/json" \
123
+ -H "Origin: https://example.com" \
124
+ -d '{"code":"550e8400-...","answer":"<SIGNALING_DATA>","side":"answerer"}'
125
+ # Returns: {"success":true}
126
+ ```
127
+
128
+ ## Architecture
129
+
130
+ ### Storage Interface
131
+
132
+ The storage layer is abstracted through a simple interface, making it easy to implement custom storage backends:
133
+
134
+ ```typescript
135
+ interface Storage {
136
+ createSession(origin: string, topic: string, info: string, offer: string, expiresAt: number): Promise<string>;
137
+ listSessionsByTopic(origin: string, topic: string): Promise<Session[]>;
138
+ getSession(code: string, origin: string): Promise<Session | null>;
139
+ updateSession(code: string, origin: string, update: Partial<Session>): Promise<void>;
140
+ deleteSession(code: string): Promise<void>;
141
+ cleanup(): Promise<void>;
142
+ close(): Promise<void>;
143
+ }
144
+ ```
145
+
146
+ ### Built-in Storage Adapters
147
+
148
+ **SQLite Storage** (`sqlite.ts`)
149
+ - For Node.js/Docker deployments
150
+ - Persistent file-based or in-memory
151
+ - Automatic session cleanup
152
+ - Simple and reliable
153
+
154
+ **Cloudflare KV Storage** (`kv.ts`)
155
+ - For Cloudflare Workers deployments
156
+ - Global edge storage
157
+ - Automatic TTL-based expiration
158
+ - Distributed and highly available
159
+
160
+ ### Custom Storage Adapters
161
+
162
+ You can implement your own storage adapter by implementing the `Storage` interface:
163
+
164
+ ```typescript
165
+ import { Storage, Session } from './storage/types';
166
+
167
+ export class CustomStorage implements Storage {
168
+ async createSession(offer: string, expiresAt: number): Promise<string> {
169
+ // Your implementation
170
+ }
171
+ // ... implement other methods
172
+ }
173
+ ```
174
+
175
+ ## Development
176
+
177
+ ### Project Structure
178
+
179
+ ```
180
+ rondevu/
181
+ ├── src/
182
+ │ ├── index.ts # Node.js server entry point
183
+ │ ├── app.ts # Hono application
184
+ │ ├── config.ts # Configuration
185
+ │ └── storage/
186
+ │ ├── types.ts # Storage interface
187
+ │ ├── sqlite.ts # SQLite adapter
188
+ │ └── codeGenerator.ts # Code generation utility
189
+ ├── Dockerfile # Docker build configuration
190
+ ├── build.js # Build script
191
+ ├── API.md # API documentation
192
+ └── README.md # This file
193
+ ```
194
+
195
+ ### Building
196
+
197
+ ```bash
198
+ # Build TypeScript
199
+ npm run build
200
+
201
+ # Run built version
202
+ npm start
203
+ ```
204
+
205
+ ### Docker Build
206
+
207
+ ```bash
208
+ # Build the image
209
+ docker build -t rondevu .
210
+
211
+ # Run with volume for persistent storage
212
+ docker run -p 3000:3000 -v $(pwd)/data:/app/data rondevu
213
+ ```
214
+
215
+ ## How It Works
216
+
217
+ 1. **Discover topics** (optional): Call `GET /` to see all active topics and peer counts
218
+ 2. **Peer A** announces availability by posting to `/:topic/offer` with peer identifier and signaling data
219
+ 3. Server generates a unique UUID code and stores the session (bucketed by Origin and topic)
220
+ 4. **Peer B** discovers available peers using `GET /:topic/sessions`
221
+ 5. **Peer B** filters out their own session using the info field to avoid self-connection
222
+ 6. **Peer B** selects a peer and posts their connection data to `POST /answer` with the session code
223
+ 7. Both peers exchange signaling data through `POST /answer` endpoint
224
+ 8. Both peers poll for updates using `POST /poll` to retrieve connection information
225
+ 9. Sessions automatically expire after the configured timeout
226
+
227
+ This allows peers in distributed systems to discover each other without requiring a centralized registry, while maintaining isolation between different applications through Origin headers.
228
+
229
+ ### Origin Isolation
230
+
231
+ Sessions are isolated by the HTTP `Origin` header, ensuring that:
232
+ - Peers can only see sessions from their own origin
233
+ - Session codes cannot be accessed cross-origin
234
+ - Topics are organized by application domain
235
+
236
+ ## License
237
+
238
+ MIT
239
+
240
+ ## Contributing
241
+
242
+ Contributions are welcome! Please feel free to submit a Pull Request.
package/build.js ADDED
@@ -0,0 +1,17 @@
1
+ // Build script using esbuild
2
+ const esbuild = require('esbuild');
3
+
4
+ esbuild.build({
5
+ entryPoints: ['src/index.ts'],
6
+ bundle: true,
7
+ platform: 'node',
8
+ target: 'node20',
9
+ outfile: 'dist/index.js',
10
+ format: 'cjs',
11
+ external: [
12
+ 'better-sqlite3',
13
+ '@hono/node-server',
14
+ 'hono'
15
+ ],
16
+ sourcemap: true,
17
+ }).catch(() => process.exit(1));